javascript - NodeJS 显示动态路由上的实时 TCP 数据

标签 javascript node.js tcp

我的最终目标如下:我的园丁有多个设备可以通过 TCP 将数据发送到我的 Node.js 服务器。该数据采用 JSON 格式,如下所示:

设备A:

{"pagename": "spacekittens", "count": 11};

设备 B:

{"pagename": "norwegiansultans", "count": 22};

由于每个流都通过 TCP 流式传输到我的服务器,因此我添加了一个 ; 来分隔每个流。此外,每个设备流中的count是随机生成的。

现在,我想为收到的每个 TCP 数据包添加动态路由,并将内容从该流显示到该路由。

所以我的路线 myserver:4000/spacekittens 应显示以下内容:

{"pagename": "spacekittens", "count": [每秒随机数]};

我的路线 myserver:4000/norwegiansultans 应该显示:

{"pagename": "norwegiansultans", "count": [每秒随机数]};

为了实现这一点,我设置了以下代码:

server.on("connection", function(socket) {
    let chunk = "";
    socket.on('data', function(data) {
        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

                // define local variables that can be used in a closure
                let json = JSON.parse(string); // Parse the current string
                let localData = data;
                console.log(json.pagename); // Function that does something with the current chunk of valid json.    
                app.get("/" + json.pagename, function(req, res) {
                    res.writeHead(200, {
                        'Content-Type': 'text/plain'
                    });
                    res.write(JSON.stringify(json));
                    res.end();
                });
            } catch (e) {
                console.log(e);
            }
            chunk = chunk.substring(d_index + 1); // Cuts off the processed chunk
            d_index = chunk.indexOf(';'); // Find the new delimiter
        }
    });
    socket.on("close", function() {
        console.log("connection closed");
    });
});

我很感激任何关于我想要完成的目标的方法论的想法和评论。然而,我发帖并不只是因为这个原因。我有个问题。

目前,我的 res.write() 行仅填充一次路由中的数据。通过套接字添加新数据不会替换我的路线上的内容。

因此,在 myserver:4000/spacekittens 路由下,我的 count 显示 11,即使我流式传输了更新的数字 ("count": 12) 我的路线 myserver:4000/spacekittens 仍然只显示 11。每次发送数据时,控制台日志记录都会给我正确的响应。所以我没有正确使用 res.write() 因为它不会覆盖旧数据。

不确定如何纠正。

最佳答案

我会将页面数据和路由设置与连接处理分开。您无法每次收到 JSON blob 时都设置相同的路由,因此这会修改应用程序路由以将数据返回给用户。数据会随着 JSON 的每个 blob 的变化而变化。

class Pages {

    constructor(app){
        this._store = {}
        this.app = app
    }

    get( name ){
        return this._store[name]
    }

    set( name, data ){
        if ( !this.exists(name) ) this.setupRoute(name)
        return this._store[name] = data
    }

    exists( name ){
        return this._store.hasOwnProperty(name)
    }

    addJSON( json_string ){
        let data = JSON.parse(json_string)
        if ( !data.pagename ) throw new Error('No pagename in data: "%s"', json_string)
        if ( !data.count ) throw new Error('No count in data "%s"', json_string)
        return this.set(data.pagename, data)
    }

    setupRoute( name ){
        let route = `/${name}`
        this.app.get(route, (req, res)=>{
            res.json(this.get(name))
        })
        console.log('setup route: %s', route)
        return this.app
    }

}

然后连接处理只处理提取 Pages 的 JSON 字符串。

const pages = new Pages(app)

server.on("connection", function(socket) {
    let chunk = "";

    socket.on('data', function(data) {
        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
                pages.addJSON(string)
            } catch (e) {
                console.error(e);
            }
            chunk = chunk.substring(d_index + 1); // Cuts off the processed chunk
            d_index = chunk.indexOf(';'); // Find the new delimiter
        }
    });

    socket.on("close", function() {
        console.log("connection closed");
    });
});

您还可以使用行分隔的 JSON 解析库之一,该库将采用二进制流并将 JSON 作为普通对象发出:

ndjsonld-jsonstream

关于javascript - NodeJS 显示动态路由上的实时 TCP 数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48536118/

相关文章:

c - 当我使用 '' 关闭发送对等方的套接字时,为什么接收对等方的套接字不断接收 "control-c"

javascript - CKEditor如何获取对话框输入

javascript - JS如何获取括号外的子字符串?

javascript - 如何从键值数组中删除一个元素?

javascript - 如何在 javascript 中使用前瞻来实现负面回顾?

c# - 套接字客户端类的异常与结果代码

javascript - 异步并行最终回调不会触发

javascript - 在后端或前端列出一个集合

sql - 如何在 node.js MSSQL 中执行具有可变表名的查询?

c# - 使用 SSL 创建 TCP 客户端连接