首页>代码>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);
	}

}
最近下载更多
飞翔的面包片  LV12 5月21日
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日
最近浏览更多
qwertasdfgkwuejwjwjw  LV1 6月27日
80730176  LV7 6月7日
飞翔的面包片  LV12 5月21日
微信网友_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日
顶部 客服 微信二维码 底部
>扫描二维码关注最代码为好友扫描二维码关注最代码为好友