我正在用netty
编写一个WebSocket服务器和客户端。
我已经覆盖了channelInactive
& exceptionCaught
。问题是当客户端关闭连接时,服务器偶尔会得到java.io.IOException: Connection reset by peer
。我了解到这是由于服务器仍在从关闭的通道读取。这是否意味着有时当客户端调用channel.close()
时,最后一条消息的IO没有完成?
我尝试在发送最后一条消息和关闭操作之间添加一个等待时间,但是即使有1秒的延迟,异常仍然发生(服务器和客户端都在本地主机上运行)。
有什么办法可以摆脱这种情况,还是我应该忽略它?
代码和错误消息如下。
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
wsHolder.remove(ctx);
List<ChannelHandlerContext> ctxList = wsHolder.getAllUserCtx();
if (ctxList.size() > 0) {
for (ChannelHandlerContext octx : ctxList) {
if (!octx.channel().id().equals(ctx.channel().id())) {
octx.channel().writeAndFlush(new UserLogout(id));
}
}
}
super.channelInactive(ctx);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
log.error("Exception in WebsocketInHandler of ctx {}: {}", wsHolder.getUserId(ctx), cause.getMessage());
log.error("Error:", cause);
if (!(ctx.channel().isActive() && ctx.channel().isWritable())) {
ctx.close();
}
}
例外消息:
java.io.IOException: Connection reset by peer
at sun.nio.ch.FileDispatcherImpl.read0(Native Method)
at sun.nio.ch.SocketDispatcher.read(SocketDispatcher.java:39)
at sun.nio.ch.IOUtil.readIntoNativeBuffer(IOUtil.java:223)
at sun.nio.ch.IOUtil.read(IOUtil.java:192)
at sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:380)
at io.netty.buffer.PooledByteBuf.setBytes(PooledByteBuf.java:253)
at io.netty.buffer.AbstractByteBuf.writeBytes(AbstractByteBuf.java:1133)
at io.netty.channel.socket.nio.NioSocketChannel.doReadBytes(NioSocketChannel.java:350)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:148)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:714)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:650)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:576)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493)
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.lang.Thread.run(Thread.java:748)
1条答案
按热度按时间jdgnovmf1#
你可以忽略它。
如果您使用正确的方法
shutdownGracefully
,Netty会正常地关闭客户端。如果您使用kill -9 pid
关闭客户端,则服务器端不会出现异常。出现异常可能是因为您在IDE中终止了它,这意味着客户端立即被不正常地关闭,并绕过了通常的握手过程。