netty 处理远程主机强制关闭一个连接,首先看下api解释:
/**
* Returns {@code true} if and only if the channel should not close itself when its remote
* peer shuts down output to make the connection half-closed. If {@code false}, the connection
* is closed automatically when the remote peer shuts down output.
*/
boolean isAllowHalfClosure();
/**
* Sets whether the channel should not close itself when its remote peer shuts down output to
* make the connection half-closed. If {@code true} the connection is not closed when the
* remote peer shuts down output. Instead,
* {@link ChannelInboundHandler#userEventTriggered(ChannelHandlerContext, Object)}
* is invoked with a {@link ChannelInputShutdownEvent} object. If {@code false}, the connection
* is closed automatically.
*/
SocketChannelConfig setAllowHalfClosure(boolean allowHalfClosure);
默认是自动关闭channel,但是这样无法捕获远程主机强制关闭一个连接异常,所以 设置serverconfig
allowHalfClosure=true
这里初始化配置可以在下面的方法中处理
/**
* This method will be called once the {@link Channel} was registered. After the method returns this instance
* will be removed from the {@link ChannelPipeline} of the {@link Channel}.
*
* @param ch the {@link Channel} which was registered.
* @throws Exception is thrown if an error occurs. In that case it will be handled by
* {@link #exceptionCaught(ChannelHandlerContext, Throwable)} which will by default close
* the {@link Channel}.
*/
protected abstract void initChannel(Channel ch) throws Exception;
像这样:
ch.config().setAllowHalfClosure(true);
就可以在
/**
* Calls {@link ChannelHandlerContext#fireUserEventTriggered(Object)} to forward
* to the next {@link ChannelInboundHandler} in the {@link ChannelPipeline}.
*
* Sub-classes may override this method to change behavior.
*/
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
ctx.fireUserEventTriggered(evt);
}
中捕获远程主机强制关闭一个连接了 想这样处理,在自己的handler中重写上面的方法:
/**
* 读取数据超时 ---> 断定连接断开 ----> 释放对应的socket连接
*
* 心跳处理
* 链路读写超时处理
*
* @param ctx
* @param evt
* @throws Exception sub_reactor ChannelInputShutdownEvent.INSTANCE
*/
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
try {
Channel channel = ctx.channel();
if (evt instanceof IdleStateEvent) {
IdleStateEvent e = (IdleStateEvent) evt;
if (e.state() == IdleState.READER_IDLE) {
channel.close(); //call back channelInactive(ChannelHandlerContext ctx)
if (logger.isDebugEnabled()) logger
.debug(channel.remoteAddress() + "---No data was received for a while ,read time out... ...");
} // because we are attaching more importance to the read_idle time(timeout to rec)
else if (e.state() == IdleState.WRITER_IDLE) { // No data was sent for a while.
channel.close();
if (logger.isDebugEnabled()) logger
.debug(channel.remoteAddress() + "---No data was sent for a while.write time out... ...");
}
} else if (evt instanceof ChannelInputShutdownEvent) {
channel.close();//远程主机强制关闭连接
}
} catch (Exception e) {
e.printStackTrace();
}
}
通过以上设置就可以捕获 并处理逻辑相关资源了 netty 处理远程主机强制关闭一个连接