websocket 当客户端关闭连接时,Netty偶尔会生成“Connection reset by peer”(连接被对等方重置)异常

beq87vna  于 2022-11-29  发布在  其他
关注(0)|答案(1)|浏览(1593)

我正在用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)
jdgnovmf

jdgnovmf1#

你可以忽略它。
如果您使用正确的方法shutdownGracefully,Netty会正常地关闭客户端。如果您使用kill -9 pid关闭客户端,则服务器端不会出现异常。出现异常可能是因为您在IDE中终止了它,这意味着客户端立即被不正常地关闭,并绕过了通常的握手过程。

相关问题