Netty断线重连
最近使用Netty开发一个中转服务,需要一直保持与Server端的连接,网络中断后需要可以自动重连,查询官网资料,实现方案很简单,核心思想是在channelUnregistered钩子函数里执行重连。
创建连接
需要把configureBootstrap重构为一个函数,方便后续复用
- EventLoopGroup group = new NioEventLoopGroup();
- private volatile Bootstrap bootstrap;
- public void init(String host, int port) throws RobotException {
- this.serverIp = host;
- this.serverPort = port;
- try {
- // 创建并初始化 Netty 客户端 Bootstrap 对象
- bootstrap = configureBootstrap(new Bootstrap(),group);
- bootstrap.option(ChannelOption.TCP_NODELAY, true);
- doConnect(bootstrap);
- }
- catch(Exception ex){
- ex.printStackTrace();
- throw new RobotException("connect remote control server error!",ex.getCause());
- }
- }
- Bootstrap configureBootstrap(Bootstrap b, EventLoopGroup g) {
- b.group(g).channel(NioSocketChannel.class)
- .remoteAddress(serverIp, serverPort)
- .handler(new ChannelInitializer<SocketChannel>() {
- @Override
- public void initChannel(SocketChannel channel) throws Exception {
- ChannelPipeline pipeline = channel.pipeline();
- // 编解码器
- pipeline.addLast(protoCodec);
- // 请求处理
- pipeline.addLast(RobotClient.this);
- }
- });
- return b;
- }
- void doConnect(Bootstrap b) {
- try {
- ChannelFuture future = b.connect();
- future.addListener(new ChannelFutureListener() {
- @Override
- public void operationComplete(ChannelFuture future) throws Exception {
- if (future.isSuccess()) {
- System.out.println("Started Tcp Client: " + serverIp);
- } else {
- System.out.println("Started Tcp Client Failed: ");
- }
- if (future.cause() != null) {
- future.cause().printStackTrace();
- }
- }
- });
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
断线重连
来看断线重连的关键代码:
- @ChannelHandler.Sharable
- public class RobotClient extends SimpleChannelInboundHandler<RobotProto> {
- @Override
- public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
- // 状态重置
- isConnected = false;
- this.serverStatus = -1;
- final EventLoop loop = ctx.channel().eventLoop();
- loop.schedule(new Runnable() {
- @Override
- public void run() {
- doConnect(configureBootstrap(new Bootstrap(), loop));
- }
- }, 1, TimeUnit.SECONDS);
- }
- }
需要注意,Client类需要添加@ChannelHandler.Sharable注解,否则重连时会报错
作者:Jadepeng
出处:jqpeng的技术记事本--http://www.cnblogs.com/xiaoqi
您的支持是对博主最大的鼓励,感谢您的认真阅读。
本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。