【问题标题】:how to create a room based on 2 users in socket.io?如何在 socket.io 中基于 2 个用户创建房间?
【发布时间】:2016-05-05 15:54:21
【问题描述】:

我的目标是创建基于两个不同用户的一对一聊天。我能想到的唯一方法是使用 socket.io 房间

但现在的问题是我如何创建独特的房间?

例如

socket.on('join', function(room) {
   socket.join(room);
});

我是否需要从客户端发出房间,如果需要,我如何使其独一无二。想象一下有成千上万的用户。

聊天应用程序,类似于 facebook 聊天应用程序。可以一对一聊天的地方。

我需要 redis 或 mongodb 来存储房间吗?任何有大规模使用 socket.io 经验的人,请分享您的意见

谢谢!

【问题讨论】:

    标签: node.js sockets socket.io


    【解决方案1】:

    一个房间总是唯一的,当你做socket.join('roomname')时,如果房间不存在,它会创建并且这个socket会加入它,如果存在这个socket就会加入它。

    因此,例如,如果您希望客户端 A 加入客户端 B 所在的房间,则可以从客户端 A 发送如下事件:

    socket.emit('joinroom', roomname);
    

    在服务器上:

    socket.on('joinroom', function(data){
         socket.join(data)
      })
    

    无论如何,当一个套接字连接时,它会自动创建并加入他自己的房间,这个房间的名称将是套接字的 id,所以我认为没有必要为基于两个不同用户的聊天创建新房间。

    您需要的只是将套接字 ID 与用户的永久属性链接起来。

    编辑:

    我给你留下一个简单的聊天应用程序示例,你可以在其中打开多个对话:

    server.js:https://gist.github.com/pacmanmulet/b30d26b9e932316f54b2

    index.html:https://gist.github.com/pacmanmulet/6481791089effb79f25f

    你可以在这里测试:https://chat-socket-io-example.herokuapp.com/

    我没有使用房间,当你想发射到一组套接字时更有意义,而不是只发射一个。 希望你能更好地理解我的想法。

    【讨论】:

    • 不需要创建房间吗?这是为什么呢?
    • 因为你可以使用创建的,如果你愿意,我可以做一个示例应用来做到这一点
    • 感谢您的帮助,如果可能的话可以给我展示一个示例应用程序吗?
    • 这太棒了,让我将它集成到我的网络应用中。
    • 大家好,我正在根据这个想法寻找线索,我只想说非常感谢您的清晰解释:) Best Reguards
    【解决方案2】:

    我尝试做一个minimal example,你一次只能在一个房间里(除了你默认的socket.id房间),并且只有在同一个房间里的其他套接字才能收到你的消息。你也可以换房间。

    基本前提是,如果socket A在房间'xyz',socket B也是,在服务器端你可以为socket A做socket.to('xyz').emit('message', 'hello'),socket B会收到消息,但是另一个连接的socket C不在房间“xyz”中的不会。

    【讨论】:

    • 感谢您的示例,但是示例是否可以说,用户 A 单击用户 B 与他聊天,然后用户 B 单击用户与他聊天。他们会在同一个房间吗?
    • 所有房间的加入和离开都是在服务器端完成的,所以用户 A 和用户 B 需要通知服务器他们想要互相交谈。您可以在客户端网页上有一个用户列表并拥有它,以便单击用户会导致socket.emit('request to chat', clickedUsername)。在服务器上,您必须计算两个用户何时单击彼此的姓名,然后在他们的每个套接字上调用.join(someString),其中someString 是唯一的。然后(服务器端)你可以调用socket.to('someString').emit('message', ...) 在它们之间发送消息。
    • 让我在github上写一个简单的聊天给你看
    • 只想知道,用房间私聊合适吗?一对一聊天。
    • 取决于您希望它的私密性。我认为通过安全连接的 WebSockets 很好,讨论对于同一房间和服务器中的任何套接字都是私有的。更进一步,您可以使用 WebRTC 之类的东西在两个客户端之间建立直接连接,让他们聊天而不需要通过服务器(一旦完成初始设置)。
    【解决方案3】:

    您可以在服务器运行时创建房间,我使用两个用户 ID 作为房间 ID,例如:'100-200' 用于演示目的。也许您可以使用一些更复杂的方法。

    【讨论】:

      【解决方案4】:

      您需要将房间号存储在某处(任何数据库)。您必须这样做,因为您必须保持服务器无状态。

      让我们假设您只为两个人创建私人聊天。房间号必须是唯一的。所以一种方法是使用用户的电子邮件 ID 并加入他们以创建一个新字符串并将其发送回用户。这很棘手,因为我们不知道字符串加入的顺序。所以我们通过一个没有在普通电子邮件名称中使用的字符串加入它们(例如:'“@!@!@!!@!@!@!')。我们可以在服务器端拆分它并比较发出结果。

      实际的消息正文将是

         {
              room:a@gmail.comb@gmail.com,
              from:a,
              message:'hi buddy how are you?'
          }
      

      客户端代码

      const roomName = a@gmail.com+'@!@!2!@!@"+b@gmail.com
      socket.emit('room', { room: roomName });
          this.socket.on('joined', data => {
              console.log('i have joined', data.room)
              store the room name room: data.room })
          })
      socket.on('chat',data=>console.log(`received chat from ${data.from} from the message room ${data.room}`)
      

      使用 '@!@!2@!@' 只是因为我们可以在服务器端将它们分开并检查房间是否已经存在。

      服务器端代码

       const room =[]//this variable you have store in database and retrieve it when needed.
      socket.on('room',data=>{
              if(room.length!=0){
                  const temp = data.room.split('!@!@2@!@!').reverse().join('!@!@2@!@!');
                  if(room.includes(temp)){
                      socket.join(temp)
                      console.log('joined room',temp)
                      socket.emit('joined',{room:temp})
                      console.log(room);
                  } else if(room.includes(data.room)){
                      socket.join(data.room)
                      console.log('joined room', data.room)
                      socket.emit('joined', { room: data.room})
                      console.log(room);
      
                  }
              }else{
                  socket.join(data.room);
                  room.push(data.room)
                  console.log('joined room',data.room);
                  socket.emit('joined', { room: data.room })
                  console.log(room);
              }
      
          })
      

      【讨论】:

      • 您好,希望您一切安好。我知道你回答这个问题已经有一段时间了,但我有一个非常相似的问题,我已经坚持了一段时间了。提前谢谢stackoverflow.com/questions/65277256/…我的房间是conversationId
      猜你喜欢
      • 1970-01-01
      • 2019-06-13
      • 2013-10-09
      • 1970-01-01
      • 1970-01-01
      • 2020-01-10
      • 2019-09-20
      • 2013-10-18
      • 2013-10-10
      相关资源
      最近更新 更多