当前位置: 首页 > 知识库问答 >
问题:

使用socket.io防止向多个房间发送消息

经伟
2023-03-14

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

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

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

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

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

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

加入:test//user1
加入:test//user2
加入:test2//user3
user1在测试中说了一些话
user2在测试中键入
user3在测试中说了一些话

房间应该通过URL GET param来动态连接,比如?room=room123

下面是nodeJS index.js代码。客户端代码与上面的github链接中的代码基本相同。我对node和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
          });
        }
      });

    });

}

共有1个答案

禹德水
2023-03-14

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

 类似资料:
  • 在socket.io中,如果要将消息发送到特定的房间,通常在服务器端使用特定的语法:。 但是客户机(我指的是在浏览器中运行的socket.io相关代码)如何指示消息应该发送到特定的房间? 还是socket.io客户端库也为此目的提供了特定的语法? 编辑:澄清一下,我上面的建议似乎起作用了,我只是不确定是否有更好的解决方案。

  • 问题内容: 该Socket.io API具有发送消息的能力 所有 的客户。 通过一台服务器和所有套接字在内存中,我知道该服务器如何向其所有客户端发送消息,这是显而易见的。但是,使用Redis来存储套接字的多台服务器呢? 如果我的客户端 a 连接到服务器 y ,客户端 b 连接到服务器 z (以及商店的Redis框),并且我在一个服务器上运行,则另一台服务器上的客户端将收到此消息。怎么样? 实际连接

  • 我正在使用socket.io构建一个应用程序 我正在使用Socket.io的房间功能,用户可以订阅5个“主题”。该主题中广播的每个消息都有一个消息类型,其中有100个。用户将只接收他们允许接收的类型的消息,这可能在30到70之间。 我的问题是:为每个主题+消息类型组合创建一个房间是否可行,这将是5×100个房间?socket.io会像这样表现良好吗?还是有更好的方法来解决这个问题?向每个单独的套接

  • 我是ActiveMQ新手。我曾尝试在activemq中实现生产者-消费者(发送者-接收器)。在我的代码中,我很容易发送 这是我的制片人 MsgProducer。Java语言 MsgConsumer.java 有谁能帮我找出向多个消费者发送信息的方法吗。提前谢谢。

  • 问题内容: 我从socket.io + node.js开始,我知道如何在本地发送消息和广播功能:-所有连接的客户端都收到相同的消息。 现在,我想知道如何向特定的客户端发送私人消息,我的意思是一个套接字,用于2个人之间的私人聊天(客户端到客户端流)。谢谢。 问题答案: 当用户连接时,它应使用唯一的用户名(例如电子邮件)向服务器发送消息。 一对用户名和套接字应存储在这样的对象中: 在客户端上,使用以下

  • 我正在存放插座。每个用户使用redis登录时的id 当这个用户的任何帖子。_id被创建时,我试图使用上面存储的socket.id向那个特定用户的套接字发出一个事件 问题是我无法使用上述代码向该特定套接字发出。我正在使用套接字。io版本