Netty Github の @normanmaurer からの回答
使用する必要があります
Channel.isWritable()
「キュー」がいっぱいかどうかを確認します。その場合は、さらに書き込むのに十分なスペースがあるかどうかを確認する必要があります。したがって、データをすばやく書き込んでクライアントに送信すると、目に見える効果が発生する可能性があります。DefaultFileRegion または ChunkedFile を介してファイルを書き込もうとすると、この種の問題を回避できます。
@normanmaurerありがとうございます、チャンネルのこの方法を見逃しました!内部で何が起こっているかを読む必要があると思います:
org.jboss.netty.handler.stream.ChunkedWriteHandler
更新: 2012/08/30 これは、私の問題を解決するために作成したコードです。
public class LimitedChannelSpeaker{
Channel channel;
final Object lock = new Object();
long maxMemorySizeB;
long size = 0;
Map<ChannelBufferRef, Integer> buffer2readablebytes = new HashMap<ChannelBufferRef, Integer>();
public LimitedChannelSpeaker(Channel channel, long maxMemorySizeB) {
this.channel= channel;
this.maxMemorySizeB = maxMemorySizeB;
}
public ChannelFuture speak(ChannelBuffer buff) {
if (buff.readableBytes() > maxMemorySizeB) {
throw new IndexOutOfBoundsException("The buffer is larger than the maximum allowed size of " + maxMemorySizeB + "B.");
}
synchronized (lock) {
while (size + buff.readableBytes() > maxMemorySizeB) {
try {
lock.wait();
} catch (InterruptedException ex) {
throw new RuntimeException(ex);
}
}
ChannelBufferRef ref = new ChannelBufferRef(buff);
ref.register();
ChannelFuture future = channel.write(buff);
future.addListener(new ChannelBufferRef(buff));
return future;
}
}
private void spoken(ChannelBufferRef ref) {
synchronized (lock) {
ref.unregister();
lock.notifyAll();
}
}
private class ChannelBufferRef implements ChannelFutureListener {
int readableBytes;
public ChannelBufferRef(ChannelBuffer buff) {
readableBytes = buff.readableBytes();
}
public void unregister() {
buffer2readablebytes.remove(this);
size -= readableBytes;
}
public void register() {
buffer2readablebytes.put(this, readableBytes);
size += readableBytes;
}
@Override
public void operationComplete(ChannelFuture future) throws Exception {
spoken(this);
}
}
}