首页>代码>Spring boot 整合netty实现Socket通信Client/Server心跳自动重连>/spring-boot-netty-server/src/main/java/com/ibest/core/netty/server/ConnectionWatchdog.java
package com.ibest.core.netty.server;

import java.util.Date;
import java.util.concurrent.TimeUnit;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.Timeout;
import io.netty.util.Timer;
import io.netty.util.TimerTask;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


@ChannelHandler.Sharable
public abstract class ConnectionWatchdog extends ChannelInboundHandlerAdapter
		implements TimerTask, ChannelHandlerHolder {

	private static final Logger logger = LoggerFactory.getLogger(ConnectionWatchdog.class);

	private Bootstrap bootstrap;
	private Timer timer;
	private final String host;
	private final int port;

	private volatile boolean reconnect = true;
	private int attempts;
	private volatile long refreshTime = 0L;
	private volatile boolean heartBeatCheck = false;
	private volatile Channel channel;

	public ConnectionWatchdog(Bootstrap boot, Timer timert, String host, int port) {
		this.bootstrap = boot;
		this.timer = timert;
		this.host = host;
		this.port = port;
	}

	public boolean isReconnect() {
		return reconnect;
	}

	public void setReconnect(boolean reconnect) {
		this.reconnect = reconnect;
	}

	@Override
	public void channelActive(final ChannelHandlerContext ctx) throws Exception {
		channel = ctx.channel();
		attempts = 0;
		refreshTime = new Date().getTime();
		if (!heartBeatCheck) {
			heartBeatCheck = true;
			channel.eventLoop().scheduleAtFixedRate(new Runnable() {
				@Override
				public void run() {
					if (new Date().getTime() - refreshTime > 10 * 1000L) {
						channel.close();
						logger.info("心跳检查失败,等待重连服务器---------");
					} else {
						logger.info("心跳检查Successs");
					}
				}
			}, 5L, 5L, TimeUnit.SECONDS);
		}
		logger.info("Connects with {}.", channel);
		ctx.fireChannelActive();
	}

	/**
	 * 因为链路断掉之后,会触发channelInActive方法,进行重连 重连11次后 不再重连
	 */
	@Override
	public void channelInactive(ChannelHandlerContext ctx) throws Exception {
		logger.warn("Disconnects with {}, doReconnect = {}", ctx.channel(), reconnect);
		if (reconnect) {
			if (attempts < 12) {
				attempts++;
			} else {
				reconnect = false;
			}
			long timeout = 2 << attempts;
			timer.newTimeout(this, timeout, TimeUnit.SECONDS);
		}
	}

	public void run(Timeout timeout) throws Exception {

		final ChannelFuture future;
		synchronized (bootstrap) {
			future = bootstrap.connect(host, port);
		}
	/*	future.addListener(new ChannelFutureListener() {

			@Override
			public void operationComplete(final ChannelFuture f) throws Exception {
				boolean succeed = f.isSuccess();
				logger.warn("Reconnects with {}, {}.", host + ":" + port, succeed ? "succeed" : "failed");
				if (!succeed) {
					f.channel().pipeline().fireChannelInactive();
				}
			}
		});*/
		future.addListener(ChannelFutureListener.CLOSE_ON_FAILURE);

	}

	@Override
	public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
		refreshTime = new Date().getTime();
		logger.info("receive msg {} from server and refreshHeatBeatTime", msg);
	}

}
最近下载更多
airongjun  LV1 2023年8月31日
huangpeng1  LV4 2023年3月13日
aixiao5213  LV1 2022年12月28日
xiaoyuer2  LV8 2022年11月22日
youwuzuichen  LV10 2022年10月28日
809204304@qq.com  LV13 2022年10月24日
格林小满  LV1 2022年10月10日
JustinXiao  LV1 2022年10月7日
adminandroot  LV1 2022年10月7日
hnfjj  LV7 2022年6月30日
最近浏览更多
微信网友_6708769316278272 2023年10月26日
暂无贡献等级
漫步的海星  LV4 2023年9月21日
airongjun  LV1 2023年8月31日
sunwu5212  LV6 2023年6月28日
海盗来了  LV20 2023年3月23日
huangpeng1  LV4 2023年3月13日
Uting  LV3 2023年2月21日
aixiao5213  LV1 2022年12月28日
shenmofeng11  LV1 2022年12月8日
zhaoxu123123  LV10 2022年12月4日
顶部 客服 微信二维码 底部
>扫描二维码关注最代码为好友扫描二维码关注最代码为好友