简体   繁体   中英

Is it possible that the messages client received is out of order as the netty server write

    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?

No it is not possible. TCP ensures that.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM