Reputation: 1162
for (int i = 1; i <= 100; i++) {
ctx.writeAndFlush(Unpooled.copiedBuffer(Integer.toString(i).getBytes(Charsets.US_ASCII)));
}
ctx.writeAndFlush(Unpooled.copiedBuffer("ABCD".getBytes(Charsets.US_ASCII))).addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
ctx.channel().close();
}
});
I write this in the channelRead() mehtod of my netty server handler, it will reponse "12345...100ABCD" back to the client as soon as the server receive a request.
As far as I see, the order of the message client received from the netty server is always "12345...100ABCD".
I don't know is this just by chance? Maybe sometime it would be "32451...ABCD100" (out of the server write order)?
Is it possible that the server execute
clientChannel.writeAndFlush(msg1);
clientChannel.writeAndFlush(msg2);
clientChannel.writeAndFlush(msg3);
but the client received msg2-msg1-msg3 or msg3-msg1-msg2 but not the write order msg1-msg2-msg3
In the proxy sample of netty project, https://github.com/netty/netty/tree/master/example/src/main/java/io/netty/example/proxy
the HexDumpProxyBackendHandler writes:
@Override
public void channelRead(final ChannelHandlerContext ctx, Object msg) throws Exception {
inboundChannel.writeAndFlush(msg).addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
if (future.isSuccess()) {
ctx.channel().read();
} else {
future.channel().close();
}
}
});
}
It makes sure that it trigger next channelRead() (That is inboundChannel.writeAndFlush(msg) in channelRead()) only if the wirteAndFlush() operation is finished.
So what's the purpose to write ctx.channel().read() in the listener and execute it when future.isSuccess() ? Isn't it to make sure that the messages writes to the client are received in a right order?
If I change it to
@Override
public void channelRead(final ChannelHandlerContext ctx, Object msg) throws Exception {
inboundChannel.writeAndFlush(msg);
ctx.channel().read();
}
Will it cause some issues?
Upvotes: 0
Views: 1272
Reputation: 1431
As EJP states either technique should guarantee the ordering. The difference between the example and how you've changed it is a question of flow control.
In the original example the inbound channel will only be read after the data has been successfully flushed to the network buffers. This guarantees that it only reads data as fast as it can send it, preventing Netty's send queue from building up and thus preventing out of memory errors.
The altered code reads as soon as the write operation is queued. If the outbound channel is unable to keep up there's a chance you could see out of memory errors if you're transferring a lot of data.
Upvotes: 1