您的位置:首页 > 其它

netty 处理远程主机强制关闭一个连接

2015-07-28 14:16 791 查看
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连接
* <p/>
* 心跳处理
* 链路读写超时处理
*
* @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 处理远程主机强制关闭一个连接
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息