代码
var websock = net.createServer(function(sock) {
sock.pipe(sock);
sock.setEncoding('utf8');
sock.setKeepAlive(true);
sock.on("data", function(d) {
console.log("websock", d);
});
sock.on('end', function() {
console.log('websock disconnected');
});
});
websock.listen(777, '127.0.0.1');
几分钟〜15分钟后,sock.on(“ data”,function(){})中的回调代码似乎无法正常工作。为什么会这样呢?我检查了console.log,没有带有字符串“ websock connected”的日志。
如果套接字没有断开并且没有错误,那么套接字连接或数据流发生了什么?
在另一端,(服务器端,数据发送者)似乎正在连续流式传输数据,而客户端(nodejs应用程序)已停止接收数据。
答案 0 :(得分:2)
此问题是由于您使用管道机制回送了在原始端从未使用过的数据(通信是单向的)而引起的:
sock.pipe(sock);
这使您的代码可以作为回显服务器。您的套接字“套接字”是双工流(即,对于接收到的传入数据来说是可读的,对于发送回的传出数据都是可写的)。
如果您不需要回复,而只需要接收数据,一个快速解决方法是只需删除“ sock.pipe(sock);”即可。行。要了解说明,请先阅读。
很可能您的数据源(您提到的MT5应用程序)连续发送数据,并且根本不读取您发送回的内容。因此,您的代码将使用sock.pipe(sock)不断回显接收到的数据,填充从未使用过的传出缓冲区。但是,Nodejs流的管道机制处理反压,这意味着当两个流(可读和可写流)通过管道连接时,如果传出缓冲区正在填充(达到高水位标记) ,可读流将暂停,以防止可写流“溢出”。
您可以在Nodejs docs中了解有关背压的更多信息。该片段特别描述了流如何处理背压:
在Node.js中,源是可读流,而使用者是可写流[...]
触发背压的时刻可以精确地缩小到Writable .write()函数的返回值。 [...]
在任何情况下,如果数据缓冲区超出highWaterMark或写队列正忙,.write()将返回false。
返回错误值时,反压系统将启动。它将暂停传入的Readable流发送任何数据,并等待直到使用者再次准备就绪。
在下面,您可以找到我的设置,以显示反压的作用位置;有两个文件,server.js和client.js。如果同时运行它们,服务器将很快写入控制台“ BACKPRESSURE”。由于服务器未处理背压(它忽略了sock.write在某个时候开始返回false),因此将填充并填充传出缓冲区,从而占用更多内存,而在您的方案中,socket.pipe正在处理背压,因此暂停了传入消息流。
服务器:
// ----------------------------------------
// server.js
var net = require('net');
var server = net.createServer(function (socket) {
console.log('new connection');
// socket.pipe(socket); // replaced with socket.write on each 'data' event
socket.setEncoding('utf8');
socket.setKeepAlive(true);
socket.on("data", function (d) {
console.log("received: ", d);
var result = socket.write(d);
console.log(result ? 'write ok' : 'BACKPRESSURE');
});
socket.on('error', function (err) {
console.log('client error:', err);
});
socket.on('end', function () {
console.log('client disconnected');
});
});
server.listen(10777, '127.0.0.1', () => {
console.log('server listening...');
});
客户:
// ----------------------------------------
// client.js
var net = require('net');
var client = net.createConnection(10777, () => {
console.log('connected to server!' + new Date().toISOString());
var count = 1;
var date;
while(count < 35000) {
count++;
date = new Date().toISOString() + '_' + count;
console.log('sending: ', date);
client.write(date + '\n');
}
});
client.on('data', (data) => {
console.log('received:', data.toString());
});
client.on('end', () => {
console.log('disconnected from server');
});