【问题标题】:Node JS net module killed/halted without any exceptionNode JS网络模块被杀死/停止,没有任何异常
【发布时间】:2020-02-09 00:55:26
【问题描述】:

我已经制作了简单的套接字通信。客户端使用 NodeJS V10.x 网络模块,很少看到 NodeJS 客户端被杀死而没有任何异常消息的有线症状。 客户端在 AWS Lambda 上运行,没有异常日志或任何失败消息。只是它已经消失了......

顺序是这样的

  1. 我的客户端连接到我的ECS服务器并成功发送命令数据。
  2. 服务器,如果它收到任何命令,它会向客户端发送ACK。当然是成功发送ACK了。
  3. 有时,客户端已经离开/杀死/停止,没有任何异常消息或登录 AWS 云手表失败。

我不知道如何追踪/修复它,请帮忙。

这是我将数据连接/发送/接收数据到服务器的功能代码,它也在 try...catch 中。

sendDirectCmd(directCmd){
    return new Promise((resolve, reject)=>{
        let socket = net.connect(port, hostname);
        socket.setTimeout(10000); // 10 sec
        socket.on('connect', async ()=>{
            try{
                log.info('[sendCmd] connected to ECS');
                await socket.write(directCmd);
                log.info('[sendCmd] Sent Cmd');
            }catch(e){
                e.message += `\n : (requester.sendCmd.socket.on) Failed to send Cmd \n`;
                log.error('Error on connect\n', e);
                reject(e);
                socket.end();
            }
        });

        socket.on('data', (data)=>{
            resolve(data);
            socket.end();
        });

        socket.on('timeout', ()=>{
            reject(new Error(`socket Timeout `));
            socket.end();               
        });

        socket.on('error', (err)=>{
            e.message += `\n : (requester.sendCmd.socket.error)socket Error `;
            reject(err);
            socket.end();                
        });
    });
}

【问题讨论】:

  • 您是否意识到 net.connect() 不期望 URL,但您正在使用函数调用 getGatewayUrl() 来获取主机名。函数是刚刚命名错误还是真的返回了一个 URL?
  • @jfriend00 getGatewayUrl() 函数会正确返回主机名(IP 地址),连接和发送数据没有问题。该问题仅在连接/发送数据后发生。

标签: node.js amazon-web-services aws-lambda


【解决方案1】:

不知道这是主要问题还是唯一问题,但是这段代码有潜在的问题:

    socket.on('data', (data)=>{
        resolve(data);
        socket.end();
    });

TCP 套接字是一个流。您在套接字一端发送的数据可以以任何大小的块到达另一端,并且不一定以与发送者发送的相同大小的块到达。这段代码似乎假设一旦任何数据到达,所有数据都在这里并且可以关闭套接字(可能会跳过仍在到达的其他数据)。除非您只通过套接字发送一个字节,否则这是不正确的。

相反,您的套接字上需要某种已知的数据格式,以便您知道何时收到完整的数据包或消息或传输,并且您必须累积数据直到完整的消息/数据包到达并且它可能以多个块的形式出现.

有很多不同的方法可以做到这一点。如果您的数据是文本,您可以使用换行符或空字符或任何其他不会出现在您的数据中的字符来标记一段文本的结尾,然后您读取数据,直到您看到指示您有完整消息的标记.如果您的数据不是文本,您可以先发送一个四字节长度,告诉您有多少字节的数据即将到来。还有许多其他可能的方法来格式化您的数据,以便您知道何时拥有完整的消息/数据包。

同样重要的是要知道,此问题可能不会出现在快速 LAN 上,但在速度较慢的链路上可能容易受到攻击,这可能会导致数据被分解成更小的数据包。

请注意,webSocket 协议有一个非常方便的预定义数据包格式,可以为您完成所有这些工作。您将需要一个 webSocket 客户端,另一端需要 webSocket 服务器才能使用它。

另见这些:

Proper way to establish boundaries for a tcp connection

Does node js "response.on('data', func(chunk))" guarantee the chunk boundary

NodeJs - TCP/IP Socket send/receive serially?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-06
    • 1970-01-01
    相关资源
    最近更新 更多