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 未正确删除频道的主要内容,如果未能解决你的问题,请参考以下文章