NodeJS 是否可以监听会议室中的加入和离开事件?

q5lcpyga  于 2023-06-22  发布在  Node.js
关注(0)|答案(5)|浏览(93)

我想做的是:

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

wribegjk1#

在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'),您将获得相同的效果。因此,您应该确保事件名称足够具体,不会意外地将其发出到文件室的“名称空间”之外。
如果你只想在一个socket加入或离开房间时发出/消耗一个 * 单一 * 事件,你需要自己编写,因为,同样,房间不是一个“东西”,而是一个“过滤器”。

velaa5lx

velaa5lx2#

我知道这个问题很老了,但对于任何通过谷歌搜索偶然发现这个问题的人来说,这就是我如何处理它的。
加入一个房间是一件很容易解释的事情,即使没有用于加入或离开房间的本地事件。

/* 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
我希望这能为我的研究和测试指明正确的方向。

r6hnlfcb

r6hnlfcb3#

最近被同样的问题困扰。下面的代码应该是你正在寻找的答案。这可能不是最优雅的解决方案,但有效。
这里的问题是,你需要使用类似于this.roomHandler.room(socket,"room1","join")的东西,而不是使用socket.join("something")

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();
yfwxisqw

yfwxisqw4#

其他的答案都过时了;有一个简单得多的方法,它不需要新的事件。
根据文档(下面的链接),从socket.io@3.1.0开始,名称空间适配器公开了四个与房间相关的事件。其中两个对我们现在很有用,即join-roomleave-room

// server.js

io.on("connection", function (socket) {
  // your main code here
});

io.of("/").adapter.on("join-room", function (room, id) {
  /* stuff */
});

io.of("/").adapter.on("leave-room", function (room, id) {
  /* stuff */
});

我强烈建议您阅读有关此主题的文档。它解释了房间如何在幕后工作,并列出了您可以收听的事件。
注意:这个答案是在socket.io@4.6.2是最新版本的时候写的。

kmbjn2e3

kmbjn2e35#

您可以使用本机“断开连接”事件。

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

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

相关问题