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

时间:2011-12-05 20:59:18

标签: javascript node.js socket.io

我想做类似的事情:

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
});

4 个答案:

答案 0 :(得分:15)

在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'),你将获得相同的效果。因此,您应该确保您的事件名称足够具体,以免意外地将其发送到房间的“命名空间”之外。

如果您只想在套接字加入或离开房间时发出/消耗单个事件,您需要自己编写,因为房间不是“事情“就像它是一个”过滤器“。

答案 1 :(得分:4)

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

即使没有加入或离开房间的本地活动,加入房间也很容易解决。

/* 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#idrandom-room

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

答案 2 :(得分:0)

最近遇到同样的问题。 下面的代码应该是您正在寻找的答案。它可能不是最优雅的解决方案,但可以。

捕获不是使用socket.join("something") 您需要使用类似this.roomHandler.room(socket,"room1","join")的东西。

class myserver{
    constructor(){


        this.io = require('socket.io')(85);
        this.io.on('connection', (socket) => {

            console.log("New User")

            this.roomHandler.room(socket,"room1","join")
            this.roomHandler.room(socket,"room2","join")
            //this.roomHandler.room(socket,"room3","join")
            this.roomHandler.room(socket,"room3","leave")


            console.log("---")
            console.log(this.roomHandler.roomsOfUser)

            socket.on('disconnect', (reason) => {
                this.roomHandler.disconnect(socket, reason)
                console.log(this.roomHandler.roomsOfUser)
            })

        })




        //Room Event Handler Definition
        this.roomHandler = {
            disconnect:(socket, reason)=>{

                if(this.roomHandler.roomsOfUser[socket.id]){
                    this.roomHandler.roomsOfUser[socket.id].forEach(room => {
                        this.roomHandler.room(socket, room, "disconnect")
                    })
                    delete this.roomHandler.roomsOfUser[socket.id];
                }
            },

            roomEvents : {},
            roomsOfUser: {},

            room:(socket,room,action)=>{//Join Or Leave
                if(typeof socket == "object" && typeof socket.join == "function"){
                    if(typeof room=="string"){

                        //Room Join
                        if(action=="join"){
                            socket.join(room)
                            this.roomHandler.roomOn(room,"join",socket)

                            //Create, append room collection for user
                            if(this.roomHandler.roomsOfUser[socket.id]){
                                this.roomHandler.roomsOfUser[socket.id].push(room)
                            }else{
                                this.roomHandler.roomsOfUser[socket.id] = [room]
                            }


                        //Room Leave
                        }else if(action == "leave"){
                            if(this.roomHandler.roomsOfUser[socket.id][room]){//Really in the room?
                                socket.leave(room)
                                this.roomHandler.roomOn(room,"leave", socket)
                            }

                        //User Disconnected
                        }else if(action == "disconnect"){
                            this.roomHandler.roomOn(room,"leave", socket)

                        }else{
                            console.log("Undefined room action.")
                        }

                    }else{ console.log("Unqualified name for room."); }
                }else{ console.error("Not a legit socket object",socket); socket.join("aaa") }
            },

            roomOn:(room, event, socket)=>{
                if (typeof this.roomHandler.roomEvents[room] == "function"){
                    this.roomHandler.roomEvents[room](event,socket)
                }else{
                    console.log(`No event found for ${room}`, this.roomHandler.roomEvents)
                }
            },

            roomRegister:(room,callback)=>{
                if (typeof room == "string" && typeof callback == "function") {
                    console.log(`Callback registered for ${room}`)
                    this.roomHandler.roomEvents[room] = callback
                }else{
                    console.log("Room name or callback is invalid.")
                }
            }
        }
        //END OF HANDLER


        //Register Functions for room events.
        this.roomHandler.roomRegister("room1",(event,socket)=>{
            console.log(`${event} for room1 BY ${socket.id}`)
        })

        this.roomHandler.roomRegister("room2",(event,socket)=>{
            console.log(`${event} for room2 BY ${socket.id}`)
        })

        this.roomHandler.roomRegister("room3",(event,socket)=>{
            console.log(`${event} for room3 BY ${socket.id}`)
        })



    }

}



const server = new myserver();

答案 3 :(得分:-1)

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

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

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