数据不在循环中通过套接字发送数据

Data not sending data over socket in loop

我正在尝试将传感器信息从 NodeJs 实例发送到另一个实例(最终在另一台服务器上)。当下面客户端代码中的 while 循环启用时,没有连接或数据发送到服务器。然而,当 while 循环被注释掉时,我得到了一个连接和数据。它只是一个数据对象,但在不循环拉取传感器数据时这是预期的。

服务器代码:

'use strict';
const net = require('net');
const PORT = 5000;
const ADDRESS = '127.0.0.1';

let server = net.createServer(onClientConnected);
server.listen(PORT, ADDRESS);

function onClientConnected(socket) {
    console.log(`New client: ${socket.remoteAddress}:${socket.remotePort}`);
    socket.destroy();
}

console.log(`Server started at: ${ADDRESS}:${PORT}`);

function onClientConnected(socket) {
    let clientName = `${socket.remoteAddress}:${socket.remotePort}`;
    console.log(`${clientName} connected.`);
    socket.on('data', (data) => {
    let m = data.toString().replace(/[\n\r]*$/, '');
    var d = {msg:{info:m}};
    console.log(`${clientName} said: ${data.toString()}`);
    socket.write(`We got your message (${m}). Thanks!\n`);
});

socket.on('end', () => {
    console.log(`${clientName} disconnected.`);
});

客户代码:

var n = require('net');
var s = n.Socket();
s.connect(5000, 'localhost');
var i2c = require('i2c-bus');
var MPU6050 = require('i2c-mpu6050');

var address = 0x68;
var i2cl = i2c.openSync(1);
var sensor = new MPU6050(i2cl, address);

//while (true) {
    var data = sensor.readSync();
    console.log(data);
    s.write(data.toString());
//}

Node 的主事件循环是单线程的,因此在任何时候都只执行一个事件。特定线程不会将控制权交还给事件循环以继续处理更多事件,直到它完成。 Socket.write 在调用时实际上并没有写入套接字;相反,它会在事件循环队列中创建一个任务。 while循环导致当前线程永不退出并有效地阻塞了事件循环,所以后续的socket写事件永远不会被处理。

用这个替换您的客户端代码应该有效并有效地实现您正在尝试做的事情:

var n = require('net');
var s = n.Socket();
s.connect(5000, 'localhost');
var i2c = require('i2c-bus');
var MPU6050 = require('i2c-mpu6050');

var address = 0x68;
var i2cl = i2c.openSync(1);
var sensor = new MPU6050(i2cl, address);

const readData = () => {
    var data = sensor.readSync();
    console.log(data);
    s.write(data.toString());
    setImmediate(readData);
}

readData();

setImmediate 表示在处理任何其他事件后执行函数,在本例中它将是来自 Socket.write 的事件。 Socket.write 函数还提供了一个回调,一旦数据写入套接字就被调用。