我的项目是做服务端的,需要和硬件设备建立一个长连接,心跳报文是客户端那边发,我这边不做处理。
我的项目目前遇到一个网上答案有限的问题:远程主机强制关闭一个连接。网上查的原因和解决方案大多是:由于远程客户端关闭连接,服务端代码不够健壮导致报错;需要增强代码健壮性。或者另一个解决方案是需要添加ctx.flush()或者ctx.close();但是ctx.flush()这个加了也会报错,而且我也不认为是远程主动关闭了链接,因为用调试助手测试远程的时候是没有问题的,所以我认为是我这边代码做了什么导致的远程关闭连接,查了一下发现如果在连接已经存在的条件下再次建立连接会导致远程出错,从而关闭连接,然后服务端读数据的时候报了远程主机强制关闭一个连接,我现在在从这边方面下手查,但是也不确定是不是这个原因,所以来问有没有大佬遇到过?
PS:项目需要通过每4秒检查读通道是否有数据来检查下发的召测是否有回传,每15分钟下发召测报文,30分钟没有读写则断开连接,这些我都是通过idleStateHandler解决的
idlestatehandler的配置:
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
socketChannel.pipeline()
.addLast("decoder", new MyDecoder())
.addLast("idleHandler",new IdleStateHandler(4,90,1860))
.addLast("serverHandler",new ServerHandler());
}
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
if (evt instanceof IdleStateEvent) {
IdleStateEvent e = (IdleStateEvent) evt;
if(e.state() == IdleState.READER_IDLE){
if(...){
origin = origin + ClassUtil.postValidate(origin);
System.out.println("重新下发: "+origin);
ctx.writeAndFlush(ClassUtil.retMsg(origin));
}
System.out.println("read idle");
}else if(e.state() == IdleState.WRITER_IDLE){
System.out.println(new Date().toString()+": write idle");
if(...){
origin = origin + ClassUtil.postValidate(origin);
System.out.println("下发: "+origin);
ctx.writeAndFlush(ClassUtil.retMsg(origin));
}
}else if(e.state() == IdleState.ALL_IDLE){
System.out.println(equipCode+" all idle,disconnect...");
ctx.disconnect();
}
}else {
super.userEventTriggered(ctx, evt);
}
return;
}