如何检查客户端是否仍然在例外的Netty服务器中连接?

时间:2012-10-15 18:03:41

标签: exception-handling netty

My Netty服务器从ChannelHandler上的exceptionCaught方法向客户端发回错误响应。如果客户端已消失,则会导致无限递归。这是堆栈跟踪片段:

at org.jboss.netty.channel.socket.nio.AbstractNioWorker.cleanUpWriteBuffer(AbstractNioWorker.java:778) ~[netty-3.5.7.Final.jar:na]
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.writeFromUserCode(AbstractNioWorker.java:501) ~[netty-3.5.7.Final.jar:na]
at org.jboss.netty.channel.socket.nio.NioServerSocketPipelineSink.handleAcceptedSocket(NioServerSocketPipelineSink.java:129) ~[netty-3.5.7.Final.jar:na]
at org.jboss.netty.channel.socket.nio.NioServerSocketPipelineSink.eventSunk(NioServerSocketPipelineSink.java:66) ~[netty-3.5.7.Final.jar:na]
at org.jboss.netty.channel.Channels.write(Channels.java:733) [netty-3.5.7.Final.jar:na]
at org.jboss.netty.channel.Channels.write(Channels.java:694) [netty-3.5.7.Final.jar:na]
at com.inversoft.cleanspeak.store.content.server.netty.ContentStoreChannelHandler.exceptionCaught(ContentStoreChannelHandler.java:68) ~[cleanspeak-content-store-2.3.jar:2.3]
at org.jboss.netty.handler.codec.frame.FrameDecoder.exceptionCaught(FrameDecoder.java:378) ~[netty-3.5.7.Final.jar:na]
at org.jboss.netty.channel.Channels.fireExceptionCaught(Channels.java:533) [netty-3.5.7.Final.jar:na]
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.cleanUpWriteBuffer(AbstractNioWorker.java:790) ~[netty-3.5.7.Final.jar:na]
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.writeFromUserCode(AbstractNioWorker.java:501) ~[netty-3.5.7.Final.jar:na]
at org.jboss.netty.channel.socket.nio.NioServerSocketPipelineSink.handleAcceptedSocket(NioServerSocketPipelineSink.java:129) ~[netty-3.5.7.Final.jar:na]
at org.jboss.netty.channel.socket.nio.NioServerSocketPipelineSink.eventSunk(NioServerSocketPipelineSink.java:66) ~[netty-3.5.7.Final.jar:na]
at org.jboss.netty.channel.Channels.write(Channels.java:733) [netty-3.5.7.Final.jar:na]
at org.jboss.netty.channel.Channels.write(Channels.java:694) [netty-3.5.7.Final.jar:na]
at com.inversoft.cleanspeak.store.content.server.netty.ContentStoreChannelHandler.exceptionCaught(ContentStoreChannelHandler.java:68) ~[cleanspeak-content-store-2.3.jar:2.3]
at org.jboss.netty.handler.codec.frame.FrameDecoder.exceptionCaught(FrameDecoder.java:378) ~[netty-3.5.7.Final.jar:na]
at org.jboss.netty.channel.Channels.fireExceptionCaught(Channels.java:533) [netty-3.5.7.Final.jar:na]
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.cleanUpWriteBuffer(AbstractNioWorker.java:790) ~[netty-3.5.7.Final.jar:na]
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.writeFromUserCode(AbstractNioWorker.java:501) ~[netty-3.5.7.Final.jar:na]
at org.jboss.netty.channel.socket.nio.NioServerSocketPipelineSink.handleAcceptedSocket(NioServerSocketPipelineSink.java:129) ~[netty-3.5.7.Final.jar:na]
at org.jboss.netty.channel.socket.nio.NioServerSocketPipelineSink.eventSunk(NioServerSocketPipelineSink.java:66) ~[netty-3.5.7.Final.jar:na]
at org.jboss.netty.channel.Channels.write(Channels.java:733) [netty-3.5.7.Final.jar:na]
at org.jboss.netty.channel.Channels.write(Channels.java:694) [netty-3.5.7.Final.jar:na]

我的问题是,在我的exceptionCaught方法中,测试客户端是否仍然存在的最佳方法是什么? e.getChannel()。isOpen()是否有效?

1 个答案:

答案 0 :(得分:1)

您可以使用channel.isConnected()进行检查,但这可能无法解决,因为写入是异步的,因此在实际写入发生时可能不再适用。我大部分时间都是这样的:

Channel channel = ...
channel.write(data).addListener(ChannelFutureListener.CLOSE);

这将确保在写入尝试后关闭通道。