我的问题是关于更改已注册频道的频道事件循环。
通道绑定到 io-eventloop 线程,来自 serverboostrap 上设置的 EventLoopGroup。好的。但是在“协议协商”之后,我想将某个通道的 io-eventloop 更改为专用的 io-eventloop。所以我做这样的事情:
channel.deregister().addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
newIoLoop.register(future.channel()).sync();
}
});
一切正常,但有一个问题:channel.eventloop 已更新,并且将使用此事件循环创建更新的 ChannelHandlerContext。但是 channel.pipeline.head 仍然绑定到旧的事件循环。这是预期的行为吗?
这会生成 AbstractNioByteChannel.NioByteUnsafe.read() 方法引发的异常:
case 2:
// Let the inbound handler drain the buffer and continue reading.
if (read) {
read = false;
pipeline.fireInboundBufferUpdated(); // event fired in the pipeline to try to read some bytes but without waiting for handler executed in another loop
if (!byteBuf.writable()) { // byteBuf may always be full and exception is raised
throw new IllegalStateException(
"an inbound handler whose buffer is full must consume at " +
"least one byte.");
}
}
就我而言,更改频道注册时更改 pipeline.head.eventloop 将解决此问题。