netty - 如何使用 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;
}
}
解决方案
您应该附加 aChannelFutureListener
以ChannelFuture
查看写入是否失败。请记住,一切都是非阻塞的,这意味着写入可能仅在某个时候发生,因此您不能只假设一旦返回未来就完成了。
ChannelFuture future = ...;
future.addListener(new ChannelFutureListener() { ...});
推荐阅读
- typescript - 用 Hugo 管道编译打字稿?
- mongodb - 如何在mongodb的响应中排除密码字段?
- r - 如何将一个变量的内容复制到 R 中的另一个变量中?
- php - production.ERROR:方法 [getContent] 在视图中不存在
- php - 如何显示这些记录特定于它们包含的数据?
- php - 在 127.0.0.1:8000 上使用 PHP 内置服务器
- python - 如果文本文件中的前 10 个字符匹配 - 写入新文件
- javascript - 如何使用 JavaScript 触发 jQuery 更改功能?
- formatting - 如何使用 PHPExcel 将百分比数字格式化为 Excel 百分比?
- javascript - three.js - “未捕获的类型错误:无法读取未定义的属性 'center' - three.js:6754”当我添加另一个网格时正在发生