最近用netty替换原来的socket,完成服务端和客户端的通信,包括单次的通信和心跳
1、服务端关闭,客户端无法捕获到异常
原因是把心跳的while循环写在了channelActive事件中,通过sleep死循环周期发送,导致exceptionCaught无法响应
正确的做法是起一个线程,进行轮询发心跳,尽快推出channelActive
2、重连报连接拒绝后挂死
try {
channelFuture = bootstrap.connect(new InetSocketAddress(host, port)).sync();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
此处connect需要抛异常,但eclipse自动提示InterruptedException,导致异常时挂起,无法跳出catch。
导致无法重复连接。
正确的做法,e强转为Exception即可,不要让eclipse提示。
3、handle报不是共享类
handle类负责实际处理,一般是addLast到channelpipe中的,每个连接都独立使用该handle对象,所以要么对象是共享的(@Share),
要么initchannel时每次给入的是不同的对象。
通常,服务端最好是每个连接都独立使用自己的handle对象,客户端因为只有一个连接,只会init一次,所以无所谓。
4、ChannelFuture f = b.bind(port).sync(); 这里的.sync()表示挂起等待结果,当然也可以在channelfuture.addListerner的方式。凡是.sync()的地方,都是这个意思
5、channel().closeFuture().sync()和channel.close是有区别的。closeFuture表示等待关闭时返回的future,而close则表示执行关闭的动作
6、优雅的退出:
workerGroup.shutdownGracefully();
bossGroup.shutdownGracefully();
7、 new NioEventLoopGroup(1)客户端应该只要1个工作线程即可。服务器视具体并发量、机器性能等情况而定
8、如何实现重连?答案很简单,写while循环重复执行bootstrap.connect方法,bootstrap可以重用,所以不需要在while中重复创建,只需要重复调用connect即可
9、连接成功后,对方关闭服务,断开连接,本地会捕获exceptionCaught事件,在事件中关闭ctx.close(),但是这样的关闭方式,不会触发异常。
如果是连接失败,则会触发异常。
10、心跳程序:客户端在channelActive时,开始启动发送心跳线程,在新的线程中轮询和sleep。注意,当服务端异常断开后,需要不断重连,此时该线程应该跑完释放,等连接成功后再重新启动,避免内存溢出。