Проблема возникает из-за того, что вы используете конвейерный механизм для отображения данных, которые никогда не используются на исходной стороне (связь однонаправлена):
sock.pipe(sock);
Это заставляет ваш код работать как эхо-сервер. Ваш сокет "sock" является дуплексным потоком (то есть как читаемым - для входящих данных, которые вы получаете, так и записываемым - для исходящих данных, которые вы отправляете обратно).
Быстрое решение, если вам не нужно отвечать, и вам просто нужно получить данные, - просто удалите "sock.pipe (sock);" линия . Чтобы узнать объяснение, читайте дальше.
Скорее всего, ваш источник данных (упомянутое вами приложение MT5) отправляет данные непрерывно, и он вообще не читает то, что вы отправляете обратно. Итак, ваш код продолжает отображать полученные данные, используя sock.pipe (sock), заполняя исходящий буфер, который никогда не используется. Однако механизм канала потоков Nodejs обрабатывает противодавление , что означает, что когда два потока (читаемый и записываемый) соединены каналом, если исходящий буфер заполняется (достигая верхнего водяного знака), читаемый поток приостановлен, чтобы предотвратить «переполнение» записываемого потока.
Подробнее о противодавлении вы можете прочитать в документах Nodejs . Этот фрагмент, в частности, описывает, как потоки обрабатывают противодавление:
В Node.js источником является поток для чтения, а потребителем - поток для записи [...]
Момент, когда срабатывает противодавление, можно сузить точно до возвращаемого значения функции .write (). [...]
В любом случае, когда буфер данных превысил highWaterMark или очередь записи в данный момент занята, .write () вернет false.
Когда возвращается ложное значение, срабатывает система противодавления. Приостановка поступающего читаемого потока от отправки любых данных и ожидание, пока потребитель не будет снова готов.
Ниже вы можете найти мои настройки, чтобы показать, где возникает обратное давление; Есть два файла, 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');
});