【问题标题】:NodeJS buffer incomplete TCP stream dataNodeJS 缓冲不完整的 TCP 流数据
【发布时间】:2018-02-01 16:52:22
【问题描述】:

我正在尝试确定我的实时服务器上的 TCP JSON 流存在问题。我发现如果通过 TCP(JSON 格式)流式传输给我的数据太大,那么它不会一直通过解析。我必须流它几次才能成功。

我使用的代码如下:

socket.once('data', function(data){
    let chunk = "";
    chunk += data.toString(); // Add string on the end of the variable 'chunk'
    let d_index = chunk.indexOf(';'); // Find the delimiter
    // While loop to keep going until no delimiter can be found
    while (d_index > -1) {         
        try {
            let string = chunk.substring(0,d_index); // Create string up until the delimiter
            let json = JSON.parse(string); // Parse the current string
            pages.addJSON(string);
            console.log(json.pagename); // Function that does something with the current chunk of valid json.    

        }
        catch(e){
            console.log(e);
        }
        chunk = chunk.substring(d_index+1); // Cuts off the processed chunk
        d_index = chunk.indexOf(';'); // Find the new delimiter
    }      
});

我的数据以 JSON 文件的形式传输给我,并使用 ; 分隔每个流。比如{"page": "something"};

我正在使用来自this question 的代码,其中一个响应警告我们应该缓冲任何不完整的代码。我想知道如何去做,因为我相信我的问题可能源于这个问题。

由于我的 JSON 流有点大,我认为很多数据在连接时没有通过,然后被我的 chunk 变量清除。

用户表示,一种可能性是通过字节大小捕获数据。不幸的是,我无法使用此选项,因为我不知道我的流会有多大。

我已经使用; 来捕获数据的端点,这就是我所知道的。

【问题讨论】:

    标签: javascript node.js sockets tcp


    【解决方案1】:

    socket.once('data', ...) 会给你带来问题,因为.once()。如果您没有在第一个 data 事件中获得所有数据,那么您将永远看不到其余的数据。根本无法保证给定数据事件有多少数据。它可以根据一系列因素而变化。在慢速链接或某处带有代理的链接上,您可能会在多个数据事件中获得较小的数据片段,如果数据很大,您几乎可以保证获得多个数据事件,因为它会填满某处的缓冲区。

    您需要使用socket.on('data', ...),这样您才能看到此事务中的所有data 事件,然后,如果您希望在完成后删除事件处理程序,您可以在阅读完所有内容后将其删除并且完成了。

    另外,请注意您从that other question 借用的代码使用socket.on(),而不是socket.once()


    您还需要将chunk 变量的定义移到事件处理程序之外,以便它从一个事件到下一个事件继续存在。

    let chunk = "";
    socket.once('data', function(data){
        chunk += data.toString(); // Add string on the end of the variable 'chunk'
        let d_index = chunk.indexOf(';'); // Find the delimiter
        ....
    

    【讨论】:

    • once 更改为 on。仍然有同样的问题。我不明白为什么这只是我的实时服务器上的一个问题。我在本地主机上运行相同的代码。如果我向我的本地主机版本发送一个数据包,一切都会完美运行。只有当我尝试将大数据发送到我的数字海洋服务器时,事情才会变得不那么一致。但是当我发送一个小得多的数据包时,一切正常。
    • @JasonChen - 查看我在答案末尾添加的内容。您需要将chunk 变量的定义移到事件处理函数本身之外,以便它可以将剩余数据从一个事件保存到下一个事件。当您使用实时服务器时,您有不同的网络(可能更繁忙和更远),这将导致交付数据的块大小不同。这是意料之中的。
    猜你喜欢
    • 2020-09-22
    • 2014-08-19
    • 1970-01-01
    • 1970-01-01
    • 2013-01-17
    • 2015-06-01
    • 2016-11-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多