最近使用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
您的支持是对博主最大的鼓励,感谢您的认真阅读。
本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。