Netty客户端断线重连实现及问题思考

《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门,即可获取!

服务端业务处理代码

=========

主要用于记录打印当前客户端连接数,当接收到客户端信息后返回“hello netty”字符串

@ChannelHandler.Sharable

public class SimpleServerHandler extends ChannelInboundHandlerAdapter {

private static final InternalLogger log = InternalLoggerFactory.getInstance(SimpleServerHandler.class);

public static final ChannelGroup channels = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);

@Override

public void channelActive(ChannelHandlerContext ctx) throws Exception {

channels.add(ctx.channel());

log.info(“客户端连接成功: client address :{}”, ctx.channel().remoteAddress());

log.info(“当前共有{}个客户端连接”, channels.size());

}

@Override

public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {

log.info(“server channelRead:{}”, msg);

ctx.channel().writeAndFlush(“hello netty”);

}

@Override

public void channelInactive(ChannelHandlerContext ctx) throws Exception {

log.info(“channelInactive: client close”);

}

@Override

public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {

if (cause instanceof java.io.IOException) {

log.warn(“exceptionCaught: client close”);

} else {

cause.printStackTrace();

}

}

}

服务端心跳检查代码

=========

当接收心跳"ping"信息后,返回客户端’'pong"信息。如果客户端在指定时间内没有发送任何信息则关闭客户端。

public class ServerHeartbeatHandler extends ChannelInboundHandlerAdapter {

private static final InternalLogger log = InternalLoggerFactory.getInstance(ServerHeartbeatHandler.class);

@Override

public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {

log.info(“server channelRead:{}”, msg);

if (msg.equals(“ping”)) {

ctx.channel().writeAndFlush(“pong”);

} else {

//由下一个handler处理,示例中则为SimpleServerHandler

ctx.fireChannelRead(msg);

}

}

@Override

public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {

if (evt instanceof IdleStateEvent) {

//该事件需要配合 io.netty.handler.timeout.IdleStateHandler使用

IdleStateEvent idleStateEvent = (IdleStateEvent) evt;

if (idleStateEvent.state() == IdleState.READER_IDLE) {

//超过指定时间没有读事件,关闭连接

log.info(“超过心跳时间,关闭和服务端的连接:{}”, ctx.channel().remoteAddress());

//ctx.channel().close();

}

} else {

super.userEventTriggered(ctx, evt);

}

}

}

编解码工具类

======

主要使用jboss-marshalling-serial编解码工具,可自行查询其优缺点,这里只是示例使用。

public final class MarshallingCodeFactory {

/** 创建Jboss marshalling 解码器 */

public static MarshallingDecoder buildMarshallingDecoder() {

//参数serial表示创建的是Java序列化工厂对象,由jboss-marshalling-serial提供

MarshallerFactory factory = Marshalling.getProvidedMarshallerFactory(“serial”);

MarshallingConfiguration configuration = new MarshallingConfiguration();

configuration.setVersion(5);

DefaultUnmarshallerProvider provider = new DefaultUnmarshallerProvider(factory, configuration);

return new MarshallingDecoder(provider, 1024);

}

/** 创建Jboss marshalling 编码器 */

public static MarshallingEncoder buildMarshallingEncoder() {

MarshallerFactory factory = Marshalling.getProvidedMarshallerFactory(“serial”);

MarshallingConfiguration configuration = new MarshallingConfiguration();

configuration.setVersion(5);

DefaultMarshallerProvider provider = new DefaultMarshallerProvider(factory, configuration);

return new MarshallingEncoder(provider);

}

}

公共实体类

=====

public class UserInfo implements Serializable {

private static final long serialVersionUID = 6271330872494117382L;

private String username;

private int age;

public UserInfo() {

}

public UserInfo(String username, int age) {

this.username = username;

this.age = age;

}

//省略getter/setter/toString

}

下面开始本文的重点,客户端断线重连以及问题思考。

客户端实现

=====

  • 刚开始启动时需要进行同步连接,指定连接次数内没用通过则抛出异常,进程退出。

  • 客户端启动后,开启定时任务,模拟客户端数据发送。

<
  • 23
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值