问题 是否有可能在房间里听取加入和离开事件?


我想做的事情如下:

var room = io.sockets.in('some super awesome room');
room.on('join', function () {
    /* stuff */
});
room.on('leave', function () {
    /* stuff */
});

这似乎不起作用。可能吗?

为了说明所需的行为:

io.sockets.on('connection', function (socket) {
    socket.join('some super awesome room'); // should fire the above 'join' event
});

6467
2017-12-05 20:59


起源

当你加入/离开,或者当别人做什么时? - cHao
我不确定我明白你在问什么。我有一个“房间”,我想知道什么时候 任何 socket连接或离开它。 - lakenen
插座不加入或离开房间。客户加入或离开房间。我认为你对客户(那不是你)感兴趣吗? - cHao
我认为你不明白这个问题。没有“我”......这是服务器端代码。根据 socket.io docs,套接字加入和离开房间: var io = require('socket.io').listen(80); io.sockets.on('connection', function (socket) { socket.join('justin bieber fans'); socket.broadcast.to('justin bieber fans').emit('new fan'); io.sockets.in('rammstein fans').emit('new non-fan'); }); - lakenen
啊。所以“房间”是一个低级别的东西,有点像多播组,而不是聊天室。 - cHao


答案:


在Socket.IO中,“房间”实际上只是一个命名空间,可帮助您将巨大的插座袋过滤到较小的插座袋中。调用 io.sockets.in('room').on('something') 将导致事件处理程序触发 一切 事件发生时房间里的插座。如果这就是你想要的东西,这样的东西应该可以做到:

var room = io.sockets.in('some super awesome room');
room.on('join', function() {
  console.log("Someone joined the room.");
});
room.on('leave', function() {
  console.log("Someone left the room.");
});

socket.join('some super awesome room');
socket.broadcast.to('some super awesome room').emit('join');

setTimeout(function() {
  socket.leave('some super awesome room');
  io.sockets.in('some super awesome room').emit('leave');
}, 10 * 1000);

需要注意的重要一点是,如果您(1)获得一个房间中所有套接字的列表并且(2)迭代它们,则调用会产生相同的效果。 emit('join') 在各个。因此,您应确保您的事件名称足够具体,以免意外地将其发送到房间的“命名空间”之外。

如果你只想发射/消耗一个  当一个套接字加入或离开一个房间时,你需要自己写一个,因为一个房间不是一个“东西”就像它是一个“过滤器”。


13
2017-12-05 21:32



a room isn't a "thing" as much as it's a "filter"  - 这就是我所担心的(我希望socket.io有更好的文档)。我想我必须写自己的房间版本......谢谢! - lakenen
我有关于参数的问题 join 处理程序 stackoverflow.com/q/16969463/37759 - dev.e.loper


我知道这个问题已经过时了,但是对于那些通过谷歌搜索偶然发现这个问题的人来说,这就是我接近它的方式。

即使没有加入或离开房间的本地事件,加入房间也很容易解释。

/* client.js */
var socket = io();
socket.on('connect', function () {
    // Join a room
    socket.emit('joinRoom', "random-room");
});

而对于服务器端

/* server.js */
// This will have the socket join the room and then broadcast 
// to all sockets in the room that someone has joined
socket.on("joinRoom", function (roomName) {
    socket.join(roomName);
    io.sockets.in(roomName).emit('message','Someone joined the room');
}

// This will have the rooms the current socket is a member of
// the "disconnect" event is after tear-down, so socket.rooms would already be empty
// so we're using disconnecting, which is before tear-down of sockets
socket.on("disconnecting", function () {
    var rooms = socket.rooms;
    console.log(rooms);
    // You can loop through your rooms and emit an action here of leaving
});

它们变得有点棘手的是当它们断开连接时,但幸运的是 disconnecting 事件被添加,发生在拆除房间里的插座之前。在上面的示例中,如果事件是 disconnect 然后房间会空着,但是 disconnecting 将拥有他们所属的所有房间。对于我们的例子,你将有两个插座将成为其中一部分的房间 Socket#id 和 random-room

我希望从我的研究和测试中指出其他人正确的方向。


2
2017-08-01 21:38





您可以使用本机“disconnect”事件。

socket.on('disconnect', function () {

        io.sockets.emit('user disconnected');
    });

-1
2017-12-05 21:02



这不是我想要的。我想为套接字创建事件处理程序 join() 和 leave() 房间,没有完全连接到服务器或从服务器断开连接(虽然断开连接 应该 结果是 "leave"事件)。 - lakenen
@camupod - 套接字不知道“房间”。房间是应用程序级别的概念,因此套接字永远不会加入或离开房间。您必须编写一些更高级别的处理程序来自行发出加入和离开事件。 - Stephen P
@StephenP - 套接字不需要了解房间。我想知道是否有可能成为一个“房间”(io.sockets.in('name'))当有什么东西加入或离开时告诉我。 - lakenen