将数据发送到 Node.js 个客户端

Send data to Node.js Clients

我正在尝试构建一个 Node.js 应用程序来监控一些 Raspberry Pi。

由于这些 Raspberries 没有静态 IP,它们每 5 秒发送一次 UDP 广播。

我可以通过 Node.js 捕获该广播,但我无法触发新函数来通知 Node.js 个客户。

我尝试了 WebSocketsServerSendEventsSocket.io

我可以使用示例代码,它们工作得很好。

但我没有足够的经验来构建将数据发送到客户端的函数。

Node.js 应用程序:

// ==============================================================================================================
// ===== 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 包的人)在线。

编辑:

在 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//////////////////////////
});

"If message is an Object pushed into Buffer" - 假设 RPI 之一打开并开始发送 UDP 消息,消息应该传递给服务器什么以便服务器可以传递它来显示:mac 地址仅因为如果它发送一些东西 你可以确定它是打开的,如果它不发送它就这么简单。还要在客户端上显示该更改您应该在服务器上初始化 TCP 套接字以将信息传递给服务器网页,以将 html 上的内容更新为 jquery。

现在是 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 则更改数据。