3
我有一个处理程序,它接收到一个channelInterestChanged
回调,然后在该回调中测试通道的isWritable()
方法,如果是,则触发下游事件writeRequest
。Netty NIO通道可写但未连接?
有时候,如果这种情况发生的正确频道正在打开通道抛出一个异常事件的原因为java.nio.channels.NotYetConnectedException
。
应isWritable() == true
是否假设isConnected() == true
还是我搞砸了?
实施例:
@Override
public void channelInterestChanged(ChannelHandlerContext ctx,
ChannelStateEvent e) throws Exception {
MyMessage msg;
while(ctx.getChannel().isWritable()){
msg = queue.poll();
Channels.write(ctx, Channels.succeededFuture(ctx.getChannel()), msg);
}
}
堆栈跟踪:
java.nio.channels.NotYetConnectedException
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.cleanUpWriteBuffer(AbstractNioWorker.java:696)
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.writeFromUserCode(AbstractNioWorker.java:421)
at org.jboss.netty.channel.socket.nio.NioClientSocketPipelineSink.eventSunk(NioClientSocketPipelineSink.java:116)
at org.jboss.netty.channel.Channels.write(Channels.java:733)
at org.jboss.netty.handler.codec.oneone.OneToOneEncoder.handleDownstream(OneToOneEncoder.java:65)
at org.jboss.netty.channel.Channels.write(Channels.java:733)
at org.jboss.netty.handler.codec.oneone.OneToOneEncoder.handleDownstream(OneToOneEncoder.java:65)
at org.jboss.netty.channel.Channels.write(Channels.java:733)
at org.jboss.netty.channel.Channels.write(Channels.java:694) <--- this call is guarded by `isWritable()`
at foo.bar.MyHandler.channelInterestChanged(MyHandler.java:44) <--- My handler
at org.jboss.netty.handler.codec.oneone.OneToOneDecoder.handleUpstream(OneToOneDecoder.java:61)
at org.jboss.netty.channel.Channels.fireChannelInterestChanged(Channels.java:361)
at org.jboss.netty.channel.Channels$3.run(Channels.java:349)
at org.jboss.netty.channel.socket.ChannelRunnableWrapper.run(ChannelRunnableWrapper.java:41)
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.processEventQueue(AbstractNioWorker.java:373)
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.run(AbstractNioWorker.java:254)
at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:35)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
我为'isConnected()'增加了一个测试来解决这个问题。我想我(错误地)认为如果通道不连接,它就不能被写入。 – Dev 2012-08-14 01:31:26
@Dev我不熟悉Netty API,但是在NIO引擎下,你应该在OP_CONNECT激发时调用'SocketChannel.finishConnect()',并且只有在返回finishConnect()时才注册'OP_WRITE'真正。 – EJP 2012-08-14 01:46:33