我的最终目标如下:我的园丁有多个设备可以通过 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 作为普通对象发出:
关于javascript - NodeJS 显示动态路由上的实时 TCP 数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48536118/