NettyIO 未正确删除频道

Posted

技术标签:

【中文标题】NettyIO 未正确删除频道【英文标题】:NettyIO not correctly removing channels 【发布时间】:2015-05-16 21:15:06 【问题描述】:

我有一个问题:Netty 没有正确删除在 handlerRemoved 方法中断开的通道。当我将客户端重新连接到服务器时,出现以下错误:

io.netty.channel.ChannelPipelineException: com.test.netty.NettyServerHandler is not a @Sharable handler, so can't be added or removed multiple times.
            at io.netty.channel.DefaultChannelPipeline.checkMultiplicity(DefaultChannelPipeline.java:464)
            at io.netty.channel.DefaultChannelPipeline.addLast0(DefaultChannelPipeline.java:136)
            at io.netty.channel.DefaultChannelPipeline.addLast(DefaultChannelPipeline.java:129)
            at io.netty.channel.DefaultChannelPipeline.addLast(DefaultChannelPipeline.java:257)
            at io.netty.channel.DefaultChannelPipeline.addLast(DefaultChannelPipeline.java:244)
            at com.test.netty.NettyServer$1.initChannel(NettyServer.java:46)
            at com.test.netty.NettyServer$1.initChannel(NettyServer.java:38)
            at io.netty.channel.ChannelInitializer.channelRegistered(ChannelInitializer.java:69)
            at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRegistered(AbstractChannelHandlerContext.java:133)
            at io.netty.channel.AbstractChannelHandlerContext.fireChannelRegistered(AbstractChannelHandlerContext.java:119)
            at io.netty.channel.DefaultChannelPipeline.fireChannelRegistered(DefaultChannelPipeline.java:733)
            at io.netty.channel.AbstractChannel$AbstractUnsafe.register0(AbstractChannel.java:449)
            at io.netty.channel.AbstractChannel$AbstractUnsafe.access$100(AbstractChannel.java:377)
            at io.netty.channel.AbstractChannel$AbstractUnsafe$1.run(AbstractChannel.java:423)
            at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:380)
            at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:357)
            at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:116)
            at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:137)
            at java.lang.Thread.run(Thread.java:818)

处理程序如下所示:

public void handlerRemoved(ChannelHandlerContext ctx) throws Exception 
    Channel incoming = ctx.channel();
    channels.remove(ctx.channel());

我正在使用 group.shutDownGracefully(); 停止客户端

handlerAdded 方法:

public void handlerAdded(ChannelHandlerContext ctx) throws Exception 
        Channel incoming = ctx.channel();
        channels.add(ctx.channel());

主服务器:

public final class NettyServer 

    public EventLoopGroup bossGroup;
    public EventLoopGroup workerGroup;
    int PORT = 14930;

    NettyServerHandler clientHandler = new NettyServerHandler();

    public NettyServer(int PORT) 
        this.PORT = PORT;
        bossGroup = new NioEventLoopGroup();
        workerGroup = new NioEventLoopGroup();
    

    public void run() throws Exception 
        try 
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup)
                    .channel(NioserverSocketChannel.class)
                    .handler(new LoggingHandler(LogLevel.INFO))
                    .childHandler(new ChannelInitializer<SocketChannel>() 
                                      @Override
                                      public void initChannel(SocketChannel ch) throws Exception 
                                          ChannelPipeline pipeline = ch.pipeline();

                                          pipeline.addLast(new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));
                                          pipeline.addLast(new StringDecoder());
                                          pipeline.addLast(new StringEncoder());
                                          pipeline.addLast(clientHandler);
                                      
                                  
                    );

            b.bind(PORT).sync().channel().closeFuture().sync();
         finally 
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        
    

handlerRemoved 方法被执行,我检查了这个从方法中打印的东西。

【问题讨论】:

【参考方案1】:

如果不是@Shareable,您不能再次添加相同的处理程序。您将需要创建一个新实例

【讨论】:

但是如果我从 handlerRemoved 的频道列表中删除它并使用新的客户端重新连接到服务器,它应该可以工作,不是吗?如果没有,我将如何创建一个新实例? 只需在initChannel方法中调用new NettyServerHandler

以上是关于NettyIO 未正确删除频道的主要内容,如果未能解决你的问题,请参考以下文章

Discord bot 未加入我所在的语音频道

停止iOS后Chromecast频道未启动频道

“直播频道”应用未检测到 TVInputService HDMI 频道

Discord JDA - 有时有效,有时无效

技术分享| 音视频多频道使用的正确姿势

删除单个频道/所有频道不起作用