看Channel#isWritable()
方法了吗?据我了解,如果写缓冲区太满,那将返回 false。
编辑:添加了使用 Channel#isWritebale() 和 highWaterMark/lowWaterMark 的简单演示。
static InetSocketAddress ADDRESS = new InetSocketAddress("localhost", 4711);
static ChannelPipeline createPipeline() {
ChannelPipeline pipeline = Channels.pipeline();
pipeline.addLast("frameDecoder", new DelimiterBasedFrameDecoder(100,
Delimiters.lineDelimiter()));
pipeline.addLast("stringDecoder", new StringDecoder(CharsetUtil.UTF_8));
pipeline.addLast("stringEncoder", new StringEncoder(CharsetUtil.UTF_8));
return pipeline;
}
public static void main(String[] args) throws Throwable {
int suspendedWrites = 0;
int N = 1000;
final CountDownLatch ready = new CountDownLatch(N);
ConnectionlessBootstrap server = new ConnectionlessBootstrap(
new NioDatagramChannelFactory());
server.setPipeline(createPipeline());
server.getPipeline().addLast("printer",
new SimpleChannelUpstreamHandler() {
@Override
public void messageReceived(ChannelHandlerContext ctx,
MessageEvent e) throws Exception {
System.out.println((String) e.getMessage());
ready.countDown();
}
});
server.bind(ADDRESS);
ClientBootstrap client = new ClientBootstrap(
new NioDatagramChannelFactory());
client.setPipeline(createPipeline());
Channel clientChannel = client.connect(ADDRESS).sync().getChannel();
NioDatagramChannelConfig config = (NioDatagramChannelConfig) clientChannel
.getConfig();
config.setWriteBufferLowWaterMark(500);
config.setWriteBufferHighWaterMark(1000);
for (int i = 0; i < N; ++i) {
String message = "Hello number " + (i + 1) + " from client\n";
if (clientChannel.isWritable())
clientChannel.write(message);
else {
clientChannel.write(message).await();
++suspendedWrites;
}
}
ready.await(1, TimeUnit.SECONDS);
client.releaseExternalResources();
client.shutdown();
server.releaseExternalResources();
server.shutdown();
System.out.println("Suspended writes: " + suspendedWrites);
System.out.println("Missed reads: " + ready.getCount());
}
运行这将显示 Channel#isWriteable() 取决于当前的写入缓冲区大小以及高水位线和低水位线的值。
更详细的实现可以监控兴趣操作的变化,并在此基础上使可写通道可用。