【问题标题】:Using Socket.io with multiple clients connecting to same server将 Socket.io 与多个连接到同一服务器的客户端一起使用
【发布时间】:2016-12-24 06:15:09
【问题描述】:

服务器-

  var dgram = require('dgram');
  var client= dgram.createSocket('udp4');

    /** @requires socket.io */
  var io = require('socket.io')(http);

  /** Array of clients created to keep track of who is listening to what*/
      var clients = [];

      io.sockets.on('connection', function(socket, username){
        /** printing out the client who joined */
        console.log('New client connected (id=' + socket.id + ').');

        /** pushing new client to client array*/
        clients.push(socket);



      /** listening for acknowledgement message */
      client.on('message', function( message, rinfo ){
        /** creating temp array to put data in */
        var temp = [];
        /**converting data bit to bytes */
        var number= req.body.size * 2
        /** acknowledgement message is converted to a string from buffer */
        var message = message.toString();
        /** cutting hex string to correspong to requested data size*/
        var data = message.substring(0, number);
        /** converting that data to decimal */
        var data = parseInt(data, 16);
        /** adding data to data array */
        temp[0] = data
        /** emitting message to html page */
        socket.emit('temp', temp);
      });

      /** listening if client has disconnected */
      socket.on('disconnect', function() {
          clients.splice(clients.indexOf(client), 1);
          console.log('client disconnected (id=' + socket.id + ').');
          clearInterval(loop);
      });
    });
  }
});

客户-

var socket = io.connect('192.168.0.136:3000');



  socket.on(temp', function(temp){
      var temp= temp.toString();
    var message= temp.split(',').join("<br>");
    $('#output').html('<output>' + message + '</output>');
  });

当客户端连接时,会向客户端发出一个名为 temp 的随机数。当一个客户端连接到服务器时,上面的代码有效。现在你怎么能每次都设置一个新的连接?因此,如果打开一个选项卡,它会返回自己的随机消息,而当另一个选项卡打开时,它会返回自己的随机消息。

【问题讨论】:

  • 您可以将 id 发送回客户端并将其保存到 localStorage(或变量或其他任何地方)。然后让客户收听专为该客户准备的“房间”。例如var uuidSocket = io(serverHost + "/" + uuid); uuidSocket.on("Info", (data:any)=&gt; { // do something on data });这个id / room 会被服务器用来通知具体的客户端。以此类推。
  • 你能给我举个更好的例子吗?
  • 我已经添加了一个答案,希望对你有帮助!

标签: javascript html node.js sockets socket.io


【解决方案1】:

你可以试试这样的: 服务器端:

// you have your socket ready and inside the on('connect'...) you handle a register event where the client passes an id if one exists else you create one.

socket.on('register', function(clientUuid){ // a client requests registration
      var id = clientUuid == null? uuid.v4() : clientUuid; // create an id if client doesn't already have one
      var nsp;
      var ns = "/" + id;

      socket.join(id);
      var nsp = app.io.of(ns); // create a room using this id that is only for this client
      clientToRooms[ns] = nsp; // save it to a dictionary for future use

      // set up what to do on connection
      nsp.on('connection', function(nsSocket){
        console.log('someone connected');

        nsSocket.on('Info', function(data){
          // just an example
        });
      });

客户端:

// you already have declared uuid, uuidSocket and have connected to the socket previously so you define what to do on register:
    socket.on("register", function(data){
      if (uuid == undefined || uuidSocket == undefined) {// first time we get id from server
        //save id to a variable
        uuid = data.uuid;

        // save to localstorage for further usage (optional - only if you want one client per browser e.g.)
        localStorage.setItem('socketUUID', uuid);

        uuidSocket = io(serverHost + "/" + uuid); // set up the room --> will trigger nsp.on('connect',... ) on the server

        uuidSocket.on("Info", function(data){
          //handle on Info
        });

// initiate the register from the client
 socket.emit("register", uuid);

【讨论】:

    【解决方案2】:

    您可以使用Broadcasting messages

    广播意味着向所有人发送消息,除了 启动它的套接字。

    服务器:

    var io = require('socket.io')(80);
    
    io.on('connection', function (socket) {
      socket.broadcast.emit('user connected');
    });
    

    【讨论】:

      【解决方案3】:

      从我在代码中看到的情况来看,每个命名空间总是有一个套接字(命名空间是 URI 的路径部分)。所以你不能为同一个命名空间创建新的套接字,因为它们都将使用同一个套接字。

      解决方案是使用dynamic namespaces with regular expressions:

      服务器

      io.of(/^\/path\/([0-9a-fA-F-]+)$/).on('connection', (socket) => {
          console.log(`${socket.nsp?.name}: new connection with id '${socket.id}'`);
          const namespace = socket.nsp?.name;
          socket.on('event_for_server', ...);
          io.of(namespace).emit('event_for_client', ...);
          socket.disconnect();
      });
      

      客户端 (java)

      final String uuid = UUID.randomUUID().toString();
      final Socket socket = IO.socket("http://.../path/" + uuid, options);
      socket.on("connect", args -> {
          socket.emit("event_for_server", ...);
      });
      socket.on("event_for_client", args -> {
          ...
      });
      

      【讨论】:

        猜你喜欢
        • 2019-01-18
        • 2012-04-14
        • 1970-01-01
        • 2019-06-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-03-15
        • 1970-01-01
        相关资源
        最近更新 更多