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

时间:2016-06-06 13:06:49

标签: javascript node.js udp

是否可以将多个客户端连接到同一个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 ? 

1 个答案:

答案 0 :(得分:5)

Yes, it is possible.

I won't go on a speech about how you should use TCP before UDP and only use UDP when absolutely necessary.

For your problem, the fact is that UDP doesn't have any "connection". You receive messages, you send messages, but there is no "connection".

So what you should do is:

  • When receiving a message from an incoming client, store the IP/Port used by the client
  • When wanting to send messages to clients, send to all the IP/Port combinations stored
  • Periodically remove old clients (for example who didn't send a message in the last 5 minutes)

You can detect when a message is received on a bound socket after the "message" event. Your code would look something like that (helped myself):

<h:outputLink value="#{request.requestURI}" >
  <f:param name="id" value="#{request.getParameter('id')}"/>
  <f:param name="somethingElse" value="#{request.getParameter('somethingElse')}"/>
  <f:param name="evenMore" value="#{request.getParameter('evenMore')}"/>
  <f:param name="displayMode" value="#{bean.nextMode}"/>
  Next Display Mode
</h:outputLink>

Now whenever your server gets an UDP message on port 5007, it will add the sender to the list of clients, and every 3 seconds it will send a message to all the clients stored. How to make the sender receive that piece of news is another story, but you can use a tool such as WireShark to confirm yourself that it was correctly sent back.

Here I didn't delete old clients but you probably should include a mechanism to store the last time they contacted you (instead of using // 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); you can for example store current time, then periodically remove old clients)

Broadcast and Multicast are probably different from what you imagine, broadcast is used for example to send a message to everyone on the local network.

相关问题