我正在尝试构建一个实时应用程序,一次发送和接收信息分配。我设法使Vertx套接字服务器和客户端正常工作,但是我面临一个问题。当我有大量数据要一次写入约1000条记录时,缓冲区似乎读取速度太快,并且部分读取了当前消息之前的消息,例如,如果我发送了两条消息
消息1“ hello world”
消息2“我在这里”
然后套接字将收到
“你好,我是世界”,然后它将收到“这里”
,但是它应该分别接收这些字符串。我该如何强制套接字一次仅接收一条消息,就像HTTP客户端使用其request.bodyHandler
方法所做的那样。在这方面的任何帮助将不胜感激。
这是我的服务器代码
NetServerOptions options = new NetServerOptions();
options.setReceiveBufferSize(max_buffer_size);
options.setSendBufferSize(max_buffer_size);
NetServer server = vertx.createNetServer(options);
server.exceptionHandler(e -> {
Debug.log("Client exception " +e.toString());
});
server.connectHandler(socket -> {
socket.exceptionHandler(e -> {
Debug.log("Client socket exception " + e.toString());
});
String host = socket.localAddress().host();
Buffer totalBuffer = Buffer.buffer();
socket.handler(buffer -> {
Debug.log("data ::" + buffer.toString());
final RecordParser parser = RecordParser.newDelimited(delemeter, h -> {
Debug.log("data SPLIT ::::::::" + h.toString());
handler.HandleUpdate(h.toString(), socket);
});
parser.handle(buffer);
});
});
这是我的客户代码:
NetClientOptions options = new NetClientOptions()
.setConnectTimeout(this.connection_timeout)
.setReconnectAttempts(this.connection_attempts)
.setReconnectInterval(this.connection_reconnect_delay)
.setReceiveBufferSize(max_buffer_size)
.setSendBufferSize(max_buffer_size);
NetClient client = this.vertx.createNetClient(options);
client.connect(this.port, ip, res -> {
if (res.succeeded()) {
System.out.println("Connected!");
this.client_socket = res.result();
Buffer totalBuffer = Buffer.buffer();
this.client_socket.handler(buffer -> {
Debug.log("data ::" +buffer.toString());
handler.HandleUpdate(buffer.toString(), null);
});
} else {
System.out.println("Failed to connect: " + res.cause().getMessage());
}
});
答案 0 :(得分:0)
问题是您没有用于正确识别不同消息的TCP协议,并且与Vert.x不相关。您将在其他任何客户端/服务器上遇到相同的问题。
例如,您需要一种识别消息的方法
通过这种方式,解码器可以正确解码消息。
如果您查看HTTP / 1协议,它就是这样做的,例如分块的编码消息:
PUT /foo HTTP/1.1\r\n
Transfer-encoding: chunked\r\n
\r\n
11\r\n
Hello World\r\n
0\r\n
\r\n
这使用了之前介绍的两种技术。
答案 1 :(得分:0)
您的错误只是对lambda的误解
您只需要更换
socket.handler(buffer -> {
Debug.log("data ::" + buffer.toString());
final RecordParser parser = RecordParser.newDelimited(delemeter, h -> {
Debug.log("data SPLIT ::::::::" + h.toString());
handler.HandleUpdate(h.toString(), socket);
});
parser.handle(buffer);
});
通过类似
socket.handler(
RecordParser.newDelimited(delemeter, h -> {
Debug.log("data SPLIT ::::::::" + h.toString());
handler.HandleUpdate(h.toString(), socket);
})
});
在第一个方法中,每次您从套接字收到消息时都创建一个新的实例解析器。您将在第二个代码中创建一个解析器实例,该实例将接收每个缓冲区并正确解析块。