Netty斷線重連
阿新 • • 發佈:2022-05-04
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); } }