我的最终目标如下:我的园丁有几个设备可以通过TCP将数据发送到我的Node.js服务器。此数据采用JSON格式,如下所示:
设备A:
{"pagename": "spacekittens", "count": 11};
设备B:
{"pagename": "norwegiansultans", "count": 22};
由于每个都通过TCP流式传输到我的服务器,我添加了一个;
来分隔每个流。此外,每个设备流中的count
是随机生成的。
现在,我想为我的每个TCP数据包添加动态路由,并将该流中的内容显示到该路由。
所以我的路线myserver:4000/spacekittens
应该显示以下内容:
{"pagename": "spacekittens", "count": [random number every second]};
我的路线myserver:4000/norwegiansultans
应该显示:
{"pagename": "norwegiansultans", "count": [random number every second]};
为了实现这一点,我设置了以下代码:
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作为普通对象发出: