我正在使用net module测试两个NodeJS实例之间的通信。
由于TCP不依赖于消息(socket.write()
),我将每条消息包装在msg "{ json: 'encoded' }";
之类的字符串中,以便单独处理它们(否则,我会收到包含随机数量的连接消息。)
我在具有桥接网络和基于Core i3的主机的CentOS 6.5 VirtualBox VM上运行两个NodeJS实例(服务器和客户端)。测试取决于客户端向服务器发出请求并等待响应:
Date.now()
)。代码非常简单:
服务器
var net = require('net');
var server = net.createServer(function(socket) {
socket.setNoDelay(true);
socket.on('data', function(packet) {
// Split packet in messages.
var messages = packet.toString('utf-8').match(/msg "[^"]+";/gm);
for (var i in messages) {
// Get message content (msg "{ content: 'json' }";). Actually useless for the test.
//var message = messages[i].match(/"(.*)"/)[1];
// Emit response:
socket.write('msg "PONG";');
}
});
});
server.listen(9999);
客户端
var net = require('net');
var WSClient = new net.Socket();
WSClient.setNoDelay(true);
WSClient.connect(9999, 'localhost', function() {
var req = 0;
var res = 0;
console.log('Start:', Date.now());
WSClient.on('data', function(packet) {
var messages = packet.toString("utf-8").match(/msg "[^"]+";/gm);
for (var i in messages) {
// Get message content (msg "{ content: 'json' }";). Actually useless for the test.
//var message = messages[i].match(/"(.*)"/)[1];
res++;
if (res === 1000) console.log('End:', Date.now());
}
});
// Emit requests:
for (req = 0; req <= 1000; req++) WSClient.write('msg "PING";');
});
我的结果是:
我对localhost的ping(ICMP)介于0.6到0.1秒之间。我没有激烈的网络流量或CPU使用率(运行SSH,FTP,Apache,Memcached和Redis)。
对于NodeJS和TCP来说,这是正常的,还是我的CentOS VM或我的低性能主机?我应该转移到另一个平台,如Java还是本机C / C ++服务器?
我认为我的项目无法接受localhost上每个请求15毫秒的延迟(平均)。
答案 0 :(得分:4)
在某些文本中包装消息并搜索正则表达式匹配是不够的。
net.Socket
和data
接口将原始TCP流作为基础数据源。只要底层TCP流具有可用数据,就会触发data
事件。
问题是,您无法控制TCP堆栈。触发data
事件的时间与代码的逻辑无关。因此,您无法保证驱动您的侦听器的data
事件只有一个,少于一个,多于一个,或者任何数量和一些剩余的消息被发送。实际上,您几乎可以保证底层TCP堆栈将数据分解为块。并且只有当一个块可用时,监听器才会触发。您当前的代码在override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell") as! UITableViewCell
cell.title.text = theWorld[indexPath.row].name
return cell
}
个事件之间没有共享状态。
你只提到延迟,但我希望如果你检查,你也会发现收到的消息数量(两端)不是你所期望的。这是因为任何部分消息都将完全丢失。如果TCP流在块1的末尾发送了一半的消息,而剩余的在块2中,则拆分的消息将被完全丢弃。
简单而强大的方法是使用像ØMQ这样的消息传递协议。您需要在两个端点上使用它。它负责将TCP流构成原子消息。
如果由于某种原因您将连接或接收来自外部来源的流量,他们可能会使用类似长度标题的内容。然后你要做的是创建一个缓冲传入流量的转换流,只有当标头中标识的数量到达时才会发出数据。
答案 1 :(得分:1)
你做过任何网络转储吗?您可能会因为启用“无延迟”而引入的开销而创建网络拥塞。套接字属性。此属性将尽快将数据发送到TCP堆栈,如果您有非常小的信息块,将导致许多TCP数据包具有较小的有效负载,从而降低传输效率并最终由于拥塞而使TCP暂停传输。如果你想使用“没有延迟”#39;对于您的套接字,请尝试增加接收套接字缓冲区,以便更快地从tcp堆栈中提取数据。如果有帮助,请告诉我们。