Jire
Jire

Reputation: 10320

Netty 5, multiple clients

I've just converted my Netty 3 software to 5 and I've come across a problem. With one client everything is absolutely fine. I can use both decoders (they switch properly) and allow me to login.

The issue arrises when I try to connect another client, regardless if the first client is still connected or not. The first client stays connected absolutely fine but the second client cannot connect at all (does not past the first decoder).

Apr 26, 2015 4:51:16 AM io.netty.channel.ChannelHandlerInvokerUtil notifyOutboundHandlerException
WARNING: Failed to fail the promise because it's done already: DefaultChannelPromise@7f3386c4(failure(io.netty.util.IllegalReferenceCountException: refCnt: 0)
io.netty.util.IllegalReferenceCountException: refCnt: 0, decrement: 1
    at io.netty.buffer.AbstractReferenceCountedByteBuf.release(AbstractReferenceCountedByteBuf.java:111)
    at io.netty.util.ReferenceCountUtil.release(ReferenceCountUtil.java:84)
    at io.netty.channel.AbstractChannel$AbstractUnsafe.write(AbstractChannel.java:791)
    at io.netty.channel.DefaultChannelPipeline$HeadContext.write(DefaultChannelPipeline.java:1278)
    at io.netty.channel.ChannelHandlerInvokerUtil.invokeWriteNow(ChannelHandlerInvokerUtil.java:158)
    at io.netty.channel.DefaultChannelHandlerInvoker.invokeWrite(DefaultChannelHandlerInvoker.java:337)
    at io.netty.channel.PausableChannelEventExecutor.invokeWrite(PausableChannelEventExecutor.java:132)
    at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:539)
    at io.netty.handler.timeout.IdleStateHandler.write(IdleStateHandler.java:267)
    at io.netty.channel.ChannelHandlerInvokerUtil.invokeWriteNow(ChannelHandlerInvokerUtil.java:158)
    at io.netty.channel.DefaultChannelHandlerInvoker.invokeWrite(DefaultChannelHandlerInvoker.java:337)
    at io.netty.channel.PausableChannelEventExecutor.invokeWrite(PausableChannelEventExecutor.java:132)
    at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:539)
    at io.netty.channel.ChannelHandlerAdapter.write(ChannelHandlerAdapter.java:265)
    at io.netty.channel.ChannelHandlerInvokerUtil.invokeWriteNow(ChannelHandlerInvokerUtil.java:158)
    at io.netty.channel.DefaultChannelHandlerInvoker$WriteTask.run(DefaultChannelHandlerInvoker.java:440)
    at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:328)
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:354)
    at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:116)
    at io.netty.util.internal.chmv8.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1412)
    at io.netty.util.internal.chmv8.ForkJoinTask.doExec(ForkJoinTask.java:280)
    at io.netty.util.internal.chmv8.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:877)
    at io.netty.util.internal.chmv8.ForkJoinPool.scan(ForkJoinPool.java:1706)
    at io.netty.util.internal.chmv8.ForkJoinPool.runWorker(ForkJoinPool.java:1661)
    at io.netty.util.internal.chmv8.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:126)

Here is my bootstrap:

EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        ServerBootstrap b = new ServerBootstrap();
        b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)
                .option(ChannelOption.SO_REUSEADDR, true)
                .childOption(ChannelOption.SO_KEEPALIVE, true)
                .childOption(ChannelOption.TCP_NODELAY, true)
                .localAddress(43594)
                .childHandler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    public void initChannel(SocketChannel ch) throws Exception {
                        ChannelPipeline p = ch.pipeline();
                        p.addLast("timeout", new IdleStateHandler(15, 0, 0));
                        p.addLast("decoder", new RS2Decoder());
                        p.addLast("handler", new ChannelHandler());
                    }
                }
        ).bind();

The first decoder:

http://pastebin.com/9FWzXSVE

The second decoder:

http://pastebin.com/n2D8RDgn

And my channel handler:

http://pastebin.com/4mdXe5jV

Upvotes: 0

Views: 840

Answers (1)

Jire
Jire

Reputation: 10320

The solution is to mark the handler as sharable via @Sharable annotation.

Upvotes: 1

Related Questions