首页 > 解决方案 > 如何使用 Netty 发送多响应数据?(第 2 部分)

问题描述

之前发过一个同名的问题,后来我改进了,但是又出现了一个新问题,所以我将它作为另一个问题发布。我想使用 Netty(4.1.51) 将多个响应数据返回给服务器上的客户端。根据我们的规范,第一个响应数据是HttpHeader和body的格式,第二个和后续数据必须返回字节数组或字符串数​​据。我正在编写以下代码,但我正在 channelContext 中执行 writeAndFlush() 方法,但客户端没有收到它。我们的客户端程序可以通过 ChannelFutureListener.CLOSE 接收它,但我们仍然可以接收连接的一些数据。

我所期望的,

[客户端] bfIn.recvLine();…第一次等待
[服务器端] chlCtx.writeAndFlush(firstData);
[客户端] (收到 firstData)
[客户端] bfIn.recvLine();…第二次等待
[服务器端] chlCtx.writeAndFlush(secondData);
[客户端] (收到 secondData)
[客户端] bfIn.recvLine();…第三次等待
[服务器端] chlCtx.writeAndFlush(thirdData);
[客户端](接收到 thirdData)
[服务器端] chlFuture.addListener(ChannelFutureListener.CLOSE)

系统的实际行为如下,

[客户端] bfIn.recvLine();…第一次等待
[服务器端] chlCtx.writeAndFlush(firstData);
[客户端] ...继续第一次等待
[服务器端] chlCtx.writeAndFlush(secondData);
[客户端] ...继续第一次等待
[服务器端] chlCtx.writeAndFlush(thirdData);
[客户端] ...继续第一次等待
[服务器端] chlFuture.addListener(ChannelFutureListener.CLOSE)
[客户端](收到连接数据 - 第一个 & 第二个 & 第三个 - )

我错过了什么?还是错了?

服务器端

ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
 .channel(NioServerSocketChannel.class)
 .childHandler(new ChannelInitializer<SocketChannel>() {
    @Override
    public void initChannel(SocketChannel ch) throws Exception {
        ch.pipeline().addLast(new ChannelHandler());
        //    :


public class ChannelHandler extends SimpleChannelInboundHandler<byte[]> {
    public void channelRead(ChannelContext chlCtx, Object msg) {
        byte[] firstData = new byte[1024];
        byte[] secondData = new byte[1024];
        byte[] thirdData = new byte[512];
        //    :
        byte[] response = Unpooled.buffer(firstData.length);
        response.writeBytes(firstData);
        ChannelFuture chlFuture = chlCtx.writeAndFlush(response);
        if (chlFuture.cause() != null){
            chlFuture.cause().printStackTrace();
        }
        // No error
        // Client program is no received data.

        response = Unpooled.buffer(secondData.length);
        response.writeBytes(secondData);
        chlFuture = chlCtx.writeAndFlush(response);
        if (chlFuture.cause() != null){
        chlFuture.cause().printStackTrace();
        }
        // No error
        // Client program is no received data.

        response = Unpooled.buffer(thirdData.length);
        response.writeBytes(thirdData);
        chlFuture = chlCtx.writeAndFlush(response);
        if (chlFuture.cause() != null){
            chlFuture.cause().printStackTrace();
        }
        // No error
        // Client program is no received data.
        //    :
        chlFuture.addListener(ChannelFutureListener.CLOSE);
        // Client program is received first&second&third data.
        //    :

}

客户端

Socket chl = new Socket();
//    :
in = new BufferedReader(new InputStreamReader(chl.getInputStream()));
while (true){
    while ((recv = in.readLine()) != null) {
        System.out.println(recv);
    }
    if (recv.substring(0,4).equals("LAST"){
        break;
    }
}

标签: netty

解决方案


您应该附加 aChannelFutureListenerChannelFuture查看写入是否失败。请记住,一切都是非阻塞的,这意味着写入可能仅在某个时候发生,因此您不能只假设一旦返回未来就完成了。

ChannelFuture future = ...;
future.addListener(new ChannelFutureListener() { ...});

推荐阅读