本章节中附带的代码是在学习Netty的第一天文章的代码基础上添加的,不清楚的朋友请先补课。
本章节是通过视屏学习后总结,如有不足:烦请各位指出。
断线重连
-
情景介绍:
客户端因为某种原因导致channel连接断开后,客户端检测到连接断开后的自动尝试连接行为。 -
情景联想:
如何知道客户端断线————>监听器
发生断线后如何重连 -
解决手段:
-需要实现了ChannelFutureListener类的监听器/** * @Description: 断线自动重连 * @Author: Lmy * @Date: 2020/10/20 5:19 下午 */ public class ListenerClientReconn implements ChannelFutureListener { private AppTimeOutClient appTimeOutClient=new AppTimeOutClient(8080,"127.0.0.1"); @Override public void operationComplete(ChannelFuture channelFuture) throws Exception { if(!channelFuture.isSuccess()){ EventLoop loop = channelFuture.channel().eventLoop(); ScheduledFuture<?> schedule = loop.schedule(new Runnable() { //当监测到断线后触发的行为 @Override public void run() { try { System.out.println("自动启动,连接服务器中————"); appTimeOutClient.run(); } catch (Exception e) { e.printStackTrace(); } } //设置监测时间长度和单位 }, 5, TimeUnit.SECONDS); }else{ System.out.println("连接成功"); } } }
-如何让监听器正常运行
在客户端启动类中获取到ChannelFuture可以设置关联监听器,代码需要进行以下修改//移除sync()方法,如果不移除,程序将一直停留在当前知道服务停止 //ChannelFuture future = bootstrap.connect().sync(); ChannelFuture future = bootstrap.connect() //添加监听类 future.addListener(new ListenerClientReconn());
当只启动客户端时,由于通道没有建立,客户端会按照设置的时间开始尝试连接。
超时监测
在一定的时间内没有接收到消息,或者没有向发送消息时需要该机制触发。
- 情景介绍:
各种挂机操作。 - 解决问题:
客户端启动类中需要进行以下修改//初始化通道配置pipelin责任链的设置 /* *超时监测 IdleStateHandler参数依次为 *readerIdleTime 没有监测到有向通道中写信息的时间 *writerIdleTime 没有监测到有接收到通道中的信息的时间 *allIdleTime 两种情况都没有的时间 *unit 时间单位 */ socketChannel.pipeline().addLast(new IdleStateHandler(5,0,0, TimeUnit.SECONDS));
客户端处理类需要重写该方法//通道连接成功后每6S发送一次信息 int i=0; while (true){ Thread.sleep(6000); future.channel().writeAndFlush(Unpooled.copiedBuffer(String.valueOf(i),CharsetUtil.UTF_8)); i++; }
每5秒会发现没有信息在通道中,然后触发一次心跳包。/** * @Date: 2020/10/20 5:00 下午 * @Param: evt 通道中的消息题 * @Author: Lmy * @Description: 发送心跳包 */ @Override public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { //IdleStateEvent 超时事件 if(evt instanceof IdleStateEvent){ IdleStateEvent event = (IdleStateEvent) evt; if(event.state()== IdleState.READER_IDLE){ System.out.println("超时"); //发送心跳包 ctx.writeAndFlush(Unpooled.copiedBuffer("心跳包",CharsetUtil.UTF_8)); } } }