【发布时间】:2022-11-29 09:28:28
【问题描述】:
我正在使用 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)
【问题讨论】:
-
AFAIK,这是正常行为。
标签: java networking websocket netty