mrniko / netty-socketio

Socket.IO server implemented on Java. Realtime java framework
Apache License 2.0
6.82k stars 1.65k forks source link

IllegalReferenceCountException breaks handleWebsocket message chaining #193

Closed brianlenz closed 9 years ago

brianlenz commented 9 years ago

We are starting to use netty-socketio on a new project (great project, by the way; thanks!), and we've uncovered what we believe to be a small bug that is preventing EncoderHandler.handleWebsocket() from successfully processing all messages in the queue. The issue is the call to out.release(). That method is intended to be used for reference counting, but it looks like the buffer is never being retained when the buffer is initially allocated, which is causing the exception.

I'm not 100% certain on the intent here, but what I can see is that nearly every time handleWebsocket is called, it errors out with a thrown exception. Under normal circumstances, you'd expect this method to never throw an exception and instead break out of the while(true) loop once the packet queue has been drained.

Is it possible that the call to out.release() just needs to be removed? Or the buffer needs to be retained originally so that it can subsequently be released?

We are running in Java 1.8 on OS X.

Stack trace below:

io.netty.util.IllegalReferenceCountException: refCnt: 0, decrement: 1
    at io.netty.buffer.AbstractReferenceCountedByteBuf.release(AbstractReferenceCountedByteBuf.java:101)
    at com.corundumstudio.socketio.handler.EncoderHandler.handleWebsocket(EncoderHandler.java:222)
    at com.corundumstudio.socketio.handler.EncoderHandler.write(EncoderHandler.java:193)
    at io.netty.channel.AbstractChannelHandlerContext.invokeWrite(AbstractChannelHandlerContext.java:658)
    at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:716)
    at io.netty.channel.AbstractChannelHandlerContext.writeAndFlush(AbstractChannelHandlerContext.java:706)
    at io.netty.channel.AbstractChannelHandlerContext.writeAndFlush(AbstractChannelHandlerContext.java:741)
    at io.netty.channel.DefaultChannelPipeline.writeAndFlush(DefaultChannelPipeline.java:895)
    at io.netty.channel.AbstractChannel.writeAndFlush(AbstractChannel.java:243)
    at com.corundumstudio.socketio.handler.ClientHead.sendPackets(ClientHead.java:151)
    at com.corundumstudio.socketio.handler.ClientHead.send(ClientHead.java:146)
    at com.corundumstudio.socketio.handler.PacketListener.onPacket(PacketListener.java:58)
    at com.corundumstudio.socketio.handler.InPacketHandler.channelRead0(InPacketHandler.java:84)
    at com.corundumstudio.socketio.handler.InPacketHandler.channelRead0(InPacketHandler.java:36)
    at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:105)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:333)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:319)
    at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:166)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:333)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:319)
    at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:787)
    at com.corundumstudio.socketio.transport.WebSocketTransport.channelRead(WebSocketTransport.java:92)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:333)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:319)
    at com.corundumstudio.socketio.transport.PollingTransport.channelRead(PollingTransport.java:109)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:333)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:319)
    at com.corundumstudio.socketio.handler.AuthorizeHandler.channelRead(AuthorizeHandler.java:115)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:333)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:319)
    at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:108)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:333)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:319)
    at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:161)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:333)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:319)
    at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:787)
    at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:130)
    at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:511)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:468)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:382)
    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.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:137)
    at java.lang.Thread.run(Thread.java:745)
mrniko commented 9 years ago

fixed in https://github.com/mrniko/netty-socketio/issues/191

brianlenz commented 9 years ago

Thanks, Nikita. We have applied the patch locally, and it seems to have fixed it.

Just curious (no pressure); do you have an idea on the ETA for v1.7.6 release?