首先要了解一下Netty4客户端的运行机制,NettyClient.java代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | public class NettyClient { private final String host; private final int port; public NettyClient(String host, int port) { this.host = host; this.port = port; } public void run() throws Exception { // Configure the client. EventLoopGroup group = new NioEventLoopGroup(); try { Bootstrap b = new Bootstrap(); b.group(group) .channel(NioSocketChannel.class) .option(ChannelOption.TCP_NODELAY, true) .handler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast( //new LoggingHandler(LogLevel.INFO), new NettyHandler()); } }); // Start the client. ChannelFuture f = b.connect(host, port).sync(); // Wait until the connection is closed. f.channel().closeFuture().sync();//运行后会在这里阻塞 } finally { // Shut down the event loop to terminate all threads. group.shutdownGracefully(); } } } |
当我们在主线程中执行 NettyClient(NettyClient).run()时,主线程会在 ChannelFuture f = b.connect(host, port).sync(); 这里阻塞,这是Netty4的一个新特性,我们利用这个特性即可创建一个定时器来实现断线重连的功能。
定时器的代码如下ReconnectTimer.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | /** * 断线重连定时器 * * @author BeiTown * @date 2014-5-16 */ public class ReconnectTimer extends TimerTask { @Override public void run() { System.out.println("正在尝试与服务器连接......"); try { new GameClient("192.168.0.146", 10046).run(); System.out.println("与服务器断开连接,尝试10秒后与服务器重新连接......"); } catch (Exception e) { System.out.println("无法连接到服务器,尝试10秒后与服务器重新连接......"); return; } } } |
当执行定时器时,定时器走到 new GameClient(“192.168.0.116″, 22222).run() 这里就会被阻塞,直到断开连接后才会继续执行后续的代码。
这里如果不捕获 new GameClient(“192.168.0.146″, 10046).run() 的异常的话会照成整个计时器的异常并终止计时器,因此需要加上 try catch 进行包裹。
最后,在Main函数中启动这个定时器即可:
1 2 3 4 |
这里稍微提一下schedule这个方法,之前测试时基于用了习惯用了scheduleAtFixedRate方法,这是基于时间修正的一个定时器方法,但在定时器长期阻塞之后,程序为了修正时间,保证平均10s执行一次的频率,在后续动作中疯狂的赶时间执行命令,因此不适合本方案,故更正为schedule这个方法,即不再基于时间修正,保证阻塞结束之后,按照每10s一次的频率执行run()中的内容。
测试:
在服务器开启之前运行客户端,打印如下
正在尝试与服务器连接......
无法连接到服务器,尝试10秒后与服务器重新连接......
正在尝试与服务器连接......
与服务器连接成功......
关闭服务器后打印如下
与服务器断开连接,尝试10秒后与服务器重新连接......
正在尝试与服务器连接......
无法连接到服务器,尝试10秒后与服务器重新连接......
正在尝试与服务器连接......
到此一个基于Netty客户端的断线重连机制就已实现完毕,如果有其他优化方案欢迎大家交流讨论。
本篇到此,谢谢关注。
BeiTown
2014-05-16