sic*_*icr 8 sockets json node.js
我已经实现了一个使用TCP套接字进行通信的客户端/服务器.我正在写入套接字的数据是字符串化的JSON.最初一切都按预期工作,但是,随着我提高写入速率,我最终遇到JSON解析错误,其中客户端的开头在旧的结尾处接收到新写入的开始.
这是服务器代码:
var data = {};
data.type = 'req';
data.id = 1;
data.size = 2;
var string = JSON.stringify(data);
client.write(string, callback());
Run Code Online (Sandbox Code Playgroud)
以下是我在客户端服务器上接收此代码的方式:
client.on('data', function(req) {
var data = req.toString();
try {
json = JSON.parse(data);
} catch (err) {
console.log("JSON parse error:" + err);
}
});
Run Code Online (Sandbox Code Playgroud)
随着费率的增加,我收到的错误是:
SyntaxError: Unexpected token {
Run Code Online (Sandbox Code Playgroud)
这似乎是下一个请求被标记到当前请求结尾的开始.
我试过用过; 作为每个JSON请求结束时的分隔符,然后使用:
var data = req.toString().substring(0,req.toString().indexOf(';'));
Run Code Online (Sandbox Code Playgroud)
然而,这种方法,而不是导致JSON解析错误似乎导致在客户端完全丢失一些请求,因为我增加了超过300每秒的写入速率.
是否有通过TCP套接字划分传入请求的最佳实践或更有效的方法?
谢谢!
sic*_*icr 27
感谢大家的解释,他们帮助我更好地理解通过TCP套接字发送和接收数据的方式.下面是我最后使用的代码的简要概述:
var chunk = "";
client.on('data', function(data) {
chunk += data.toString(); // Add string on the end of the variable 'chunk'
d_index = chunk.indexOf(';'); // Find the delimiter
// While loop to keep going until no delimiter can be found
while (d_index > -1) {
try {
string = chunk.substring(0,d_index); // Create string up until the delimiter
json = JSON.parse(string); // Parse the current string
process(json); // Function that does something with the current chunk of valid json.
}
chunk = chunk.substring(d_index+1); // Cuts off the processed chunk
d_index = chunk.indexOf(';'); // Find the new delimiter
}
});
Run Code Online (Sandbox Code Playgroud)
欢迎评论......
使用分隔符,你在正确的轨道上.但是,您不能只在分隔符之前提取内容,处理它,然后丢弃它后面的内容.你必须缓冲分隔符后得到的任何内容,然后连接它旁边的内容.这意味着在给定data事件之后,您最终可能会得到任何数字(包括0)的JSON"块" .
基本上你保留一个缓冲区,你初始化为"".在每个data事件上,您将收到的任何内容连接到缓冲区的末尾,然后将split 它连接到分隔符上的缓冲区.结果将是一个或多个条目,但最后一个可能不完整,因此您需要测试缓冲区以确保它以分隔符结束.如果没有,则弹出最后一个结果并将缓冲区设置为它.然后,您处理剩余的结果(可能不是任何结果).