【问题标题】:Prevent emiting message to multiple rooms using socket.io使用 socket.io 防止向多个房间发送消息
【发布时间】:2018-06-15 21:38:15
【问题描述】:

我使用这个单聊天室示例作为参考设置了一个多房间 socket.io / nodeJS 聊天服务器:

https://raw.githubusercontent.com/socketio/socket.io/master/examples/chat/index.js

我使用这个文档将代码从单房间修改为多房间:

https://socket.io/docs/rooms-and-namespaces/

我还修改了代码以在端口 8080 上使用 HTTPS 而不是 HTTP。

我已经实现了多个房间。但是,随着新用户加入不同的聊天室,他们的消息会发送到所有其他聊天室。我想这可能是因为每个人都加入了原来的房间。我的节点控制台日志中的示例:

加入:测试 //user1
加入:测试 //user2
加入:test2 //user3
user1 在测试中说了些什么
user2 正在输入 test
user3 在测试中说了些什么

房间应该通过 URL GET 参数动态加入,例如 ?room=room123

这里是 nodeJS index.js 代码。客户端代码与上面的 github 链接中的代码几乎相同。我对节点和 JS 相当陌生。有什么想法吗?

// Setup basic express server
var express = require('express');
var app     = express();
var path    = require('path');
var fs      = require('fs');
var https   = require('https');
var url     = require('url');

var privateKey  = fs.readFileSync('/etc/letsencrypt/live/hostname/privkey.pem', 'utf8');
var certificate = fs.readFileSync('/etc/letsencrypt/live/hostname/fullchain.pem', 'utf8');
var credentials = {key: privateKey, cert: certificate};
var server = https.createServer(credentials, app);


var io = require('socket.io')(server);
var port = process.env.PORT || 8080;

/* CONSOLE COLORS */
var GREEN  = '\033[0;32m';
var LBLUE  = '\033[1;34m';
var BLUE   = '\033[0;34m';
var RED    = '\033[0;31m';
var YELLOW = '\033[0;33m';
var PURPLE = '\033[0;35m';
var NC     = '\033[0m'; // No Color Reset

/* Chatroom Settings */
var numUsers = 0;
var roomID = null;


server.listen(port, function () {
  console.log('HTTPS Server listening on port ' + GREEN + '%d' + NC, port);
});

/* Routing */
app.use(express.static(path.join(__dirname, 'public')));


chat();



function chat(){

  // multiple rooms
  io.on('connection', function(socket){
    var addedUser = false;
    var referer = url.parse(socket.handshake.headers.referer);
    var query = (referer.query).split("=");
    roomID = query[1];
    socket.join(roomID);


/* // attempt to resolve issue of sending messages to all rooms
console.log(socket.adapter.sids);
    if(Object.keys(socket.adapter.sids).length < 1){
      console.log('Connecting to room:' + roomID);
      socket.join(roomID);
    }
*/

    console.log("Joining: " + YELLOW + roomID + NC);
    //console.log("UUID: " + Object.keys(socket.adapter.nsp.connected)[0]);
    //console.log("unique room id:" + Object.keys(socket.adapter.sids));


    // when the client emits 'new message', this listens and executes
    socket.on('new message', function (data) {
      // we tell the client to execute 'new message'
      socket.to(roomID).emit('new message', {
        username: socket.username,
        message: data
      });

      console.log(socket.username + ' said something in \t' + YELLOW + roomID + NC);
    });

    // when the client emits 'add user', this listens and executes
    socket.on('add user', function (username) {
      if (addedUser) return;
      // we store the username in the socket session for this client
      socket.username = username;
      ++numUsers;
      addedUser = true;
      socket.emit('login', {
        numUsers: numUsers,
    });

      // echo to room that a person has connected
      socket.to(roomID).emit('user joined', {
        username: socket.username,
        numUsers: numUsers
      });

    });

    // when the client emits 'typing', we broadcast it to others
    socket.on('typing', function () {
      console.log(socket.username + ' is typing in \t' + YELLOW + roomID + NC);
      socket.to(roomID).emit('typing', {
        username: socket.username
      });
    });

    // when the client emits 'stop typing', we broadcast it to others
    socket.on('stop typing', function () {
      socket.to(roomID).emit('stop typing', {
        username: socket.username
      });
    });

      // when the user disconnects.. perform this
      socket.on('disconnect', function () {
        console.log(socket.username + PURPLE + ' disconnected' + NC
                                    + ' from ' + YELLOW + roomID + NC);
        if (addedUser) {
          --numUsers;
          // echo that this client has left
          socket.to(roomID).emit('user left', {
            username: socket.username,
            numUsers: numUsers
          });
        }
      });

    });

}

【问题讨论】:

    标签: node.js socket.io chat


    【解决方案1】:

    问题最终是由全局“var roomID”变量引起的。一旦我在所有 socket.to(query[1]).emit 函数中使用了 query[1] 变量,它就起作用了。

    【讨论】:

      【解决方案2】:

      我在您的代码中看到所有套接字都使用相同的 roomID 变量。他们每个人都需要有自己的roomID 变量。

      【讨论】:

      • roomID 变量是通过 URL 设置的。我不确定你的意思。
      • 您通过roomID 存储房间值,它在chat 函数之外声明
      • 我认为它是一个全局变量。控制台日志每次都显示正确的 roomID。
      • 一个全局变量应该在所有连接之间共享,但是你的连接可能有不同的roomID 对吧?
      • 如果我控制台记录了它正确显示的 roomID,就像在 URL 中一样。你有什么建议我做的不同吗?
      猜你喜欢
      • 2013-08-20
      • 1970-01-01
      • 2023-03-27
      • 1970-01-01
      • 2019-03-12
      • 2017-09-27
      • 1970-01-01
      • 2021-09-04
      • 1970-01-01
      相关资源
      最近更新 更多