我正在尝试构建一个 Node.js 应用来监控一些Raspberry Pi。
由于这些覆盆子没有静态IP,他们每5秒发送一次UDP广播。
我能够通过 Node.js 捕获广播,但我未能触发新功能来通知 Node.js 客户端。
我尝试了WebSockets
,ServerSendEvents
和Socket.io
。
我能够使用示例代码并且它们工作得很好。
但我没有经验足以建立一个将数据发送给客户的功能。
Node.js App:
// ==============================================================================================================
// ===== Dependencies ===========================================================================================
// ==============================================================================================================
var dgram = require('dgram');
var http = require('http');
var url = require("url");
var path = require("path");
var fs = require("fs");
// ==============================================================================================================
// ===== HTTP Serv ==============================================================================================
// ==============================================================================================================
var server = http.createServer(function(request, response) {
var uri = url.parse(request.url).pathname, filename = path.join(process.cwd(), uri);
var contentTypesByExtension = {
'.html': "text/html",
'.css': "text/css",
'.js': "text/javascript",
'.svg': "image/svg+xml"
};
fs.exists(filename, function(exists) {
if(!exists) {
response.writeHead(404, {"Content-Type": "text/plain"});
response.write("404 Not Found\n");
response.end();
return;
}
if (fs.statSync(filename).isDirectory()) filename += '/index.html';
fs.readFile(filename, "binary", function(err, file) {
if(err) {
response.writeHead(500, {"Content-Type": "text/plain"});
response.write(err + "\n");
response.end();
return;
}
var headers = {};
var contentType = contentTypesByExtension[path.extname(filename)];
if (contentType) headers["Content-Type"] = contentType;
response.writeHead(200, headers);
response.write(file, "binary");
response.end();
});
});
});
// ==============================================================================================================
// ===== HeartBeat Broadcast ====================================================================================
// ==============================================================================================================
var bcast = dgram.createSocket('udp4');
bcast.on('message', function (message) {
console.log("Triggered: UDP Broadcast");
// If UDP Broadcast is received, send message/data to client.
});
bcast.bind(5452, "0.0.0.0");
// ==============================================================================================================
// ===== Start Server ===========================================================================================
// ==============================================================================================================
server.listen(80);
console.log("Static file server running/\nCTRL + C to shutdown");

修改 我想我没有准确地解释自己。 我不想发回UDP消息。 此UDP广播应触发(Node.js)事件,该事件应更新html并将raspberry pi(发送UDP包)显示为在线。
答案 0 :(得分:0)
修改强>
来自nodejs(DOCUMENTATION)官方页面的文档:
var socket = require('socket.io')(http);
var bcast = dgram.createSocket('udp4');
bcast.bind(5452, "0.0.0.0");
bcast.on('message', function (message, remote) {
////if message is an Object pushed into Buffer////
message = message.toString('utf8');
socket.emit("HTML_Update", message);
//////////////////////////////////Solution for unedited question//////////////////////////
// var msgBuffer = Buffer.from(message.toString(); //creating a buffer //
// bcast.send(msgBuffer, 0, msgBuffer.length, remote.port, remote.address, (err) => { //
// bcast.close(); //
// }); //sending message to remote.address:remote.port (like localhost:23456) //
// //
// **build a function which will send data to the clients** //
//////////////////////////////////Solution for unedited question//////////////////////////
});
"如果消息是一个被推入缓冲区的对象" - 让我们说其中一个RPI打开并开始发送UDP消息,该消息应该传递给服务器,以便服务器可以将它传递给显示:mac地址只是因为它发送的东西你可以确定它打开,如果没有发送它简单的那样。还要在客户端上显示更改您应该在服务器上初始化TCP套接字以将信息传递到服务器网页以使用jquery更新html上的内容。
现在这里是HTML java脚本部分(我个人制作main.js文件并将所有java脚本写入其中并使用将其作为src导入到html中)。在main.js中使用jquery:
$(document).ready(function() {
var time = new Date();
var rpi = {
"list" : ["mac1", "mac2", "mac3"],
"time" : [time.getTime(), time.getTime(), time.getTime()],
"label" : ["label_ID1", "label_ID2", "label_ID3"]};
var socket = io.connect('http://your_server_address:80');
setInterval( function(){
for (var i = 0; i <= 2; i++){
if((rpi.time[i] + 10000) < time.getTime()){
$(rpi.label[i]).text("RPI " + rpi.list[i] + " is DOWN");
}
}
}, 5000);
socket.on("HTML_Update", function(data){
for (var i = 0; i<=2; i++) {
if (data.toString().equals(rpi.list[i])) {
$(rpi.label[i]).text("RPI: "+ rpi.list[i] + " is UP");
rpi.time[i] = time.getTime();
}
}
});
}
如果您在html中放置文本标签以显示特定rpi是向上还是向下,则此部分代码适用于此方案:
多个RPI +服务器 - RPI将带有mac的UDP数据发送到服务器。服务器设备用于接收数据并在任何设备上显示为网页,并在RPI为UP / DOWN时更改数据。