2012-08-02 86 views
3

我有一個處理程序,它接收到一個channelInterestChanged回調,然後在該回調中測試通道的isWritable()方法,如果是,則觸發下游事件writeRequestNetty 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) 

回答

5

可連接的和可寫的是在引擎蓋下的相同的條件。確保首先測試可連接性,當它觸發時完成連接,並且如果成功則失去對可連接狀態/事件的所有興趣。在連接完成之前,請勿注意寫入興趣。

+0

我爲'isConnected()'增加了一個測試來解決這個問題。我想我(錯誤地)認爲如果通道不連接,它就不能被寫入。 – Dev 2012-08-14 01:31:26

+0

@Dev我不熟悉Netty API,但是在NIO引擎下,你應該在OP_CONNECT激發時調用'SocketChannel.finishConnect()',並且只有在返回finishConnect()時才註冊'OP_WRITE'真正。 – EJP 2012-08-14 01:46:33