在 NodeJS 中使用 UDP 连接到同一服务器的多个客户端

Multiple Clients connected to the same Server using UDP in NodeJS

是否可以让多个客户端连接到同一个 UDP 服务器? 我想向所有连接的客户端广播相同的数据。

这将是一个开始示例,如果它以某种方式帮助...

// Server
var news = [
  "Borussia Dortmund wins German championship",
  "Tornado warning for the Bay Area",
  "More rain for the weekend"
];

var dgram = require('dgram');
var server = dgram.createSocket("udp4");
server.bind(function() {
  server.setBroadcast(true)
  server.setMulticastTTL(128);
  setInterval(broadcastNew, 3000);
});

function broadcastNew() {
  var message = new Buffer(news[Math.floor(Math.random() * news.length)]);
  server.send(message, 0, message.length, 5007, "224.1.1.1");
  console.log("Sent " + message + " to the wire...");
}

// Client 1
var PORT = 5007;
var dgram = require('dgram');
var client = dgram.createSocket('udp4');

client.on('listening', function() {
  var address = client.address();
  console.log('UDP Client listening on ' + address.address + ":" + address.port);
  client.setBroadcast(true)
  client.setMulticastTTL(128);
  client.addMembership('224.1.1.1');
});

client.on('message', function(message, remote) {
  console.log('A: Epic Command Received. Preparing Relay.');
  console.log('B: From: ' + remote.address + ':' + remote.port + ' - ' + message);
});

client.bind(PORT);

// Client 2

// Here would go another client, it is possible ? 

是的,有可能。

我不会继续讲如何在 UDP 之前使用 TCP,并且只在绝对必要时才使用 UDP。

对于您的问题,事实是 UDP 没有任何 "connection"。你收到消息,你发送消息,但是没有"connection"。

所以你应该做的是:

  • 当收到来自传入客户端的消息时,存储客户端使用的IP/Port
  • 当要向客户端发送消息时,发送至存储的所有 IP/Port 组合
  • 定期删除旧客户(例如过去 5 分钟内未发送消息的客户)

您可以检测在 "message" 事件后绑定套接字何时收到消息。您的代码看起来像这样 (helped myself):

// Server
var news = [
  "Borussia Dortmund wins German championship",
  "Tornado warning for the Bay Area",
  "More rain for the weekend"
];

var clients = {};

const dgram = require('dgram');
const server = dgram.createSocket('udp4');

server.on('error', (err) => {
  console.log(`server error:\n${err.stack}`);
  server.close();
});

server.on('message', (msg, rinfo) => {
  console.log(`server got: ${msg} from ${rinfo.address}:${rinfo.port}`);

  clients[JSON.stringify([rinfo.address, rinfo.port])] = true;
  //use delete clients[client] to remove from the list of clients
});

function broadCastNew() {
    var message = new Buffer(news[Math.floor(Math.random() * news.length)]);

    for (var client in clients) {
        client = JSON.parse(client);
        var port = client[1];
        var address = client[0];
        server.send(message, 0, message.length, port, address);
    }

    console.log("Sent " + message + " to the wire...");
}

server.on('listening', () => {
  var address = server.address();
  console.log(`server listening ${address.address}:${address.port}`);

  setInterval(broadcastNew, 3000);
});

server.bind(5007);

现在每当您的服务器在端口 5007 上收到 UDP 消息时,它会将发件人添加到客户端列表中,并且每 3 秒它会向所有存储的客户端发送一条消息。如何让发件人收到那条消息是另一回事,但您可以使用 WireShark 等工具来确认自己是否已正确发回。

这里我没有删除旧客户,但你可能应该包括一种机制来存储他们最后一次联系你的时间(而不是使用 = true 你可以存储当前时间,然后定期删除旧客户)

Broadcast和Multicast可能跟你想象的不一样,broadcast是用来给本地网络上的每个人发送消息。