我有一个问题: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方法被执行,我检查了此方法的打印内容。
最佳答案
如果不是@Sharable,则无法再次添加相同的处理程序。您将需要创建一个新实例