【问题标题】:Is it possible to listen for join and leave events on a room?是否可以在房间中收听加入和离开事件?
【发布时间】:2012-01-13 13:50:08
【问题描述】:

我想做这样的事情:

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

【问题讨论】:

  • 加入/离开时,还是其他人加入/离开时?
  • 我不确定我是否明白你在问什么。我有一个“房间”,我想知道任何套接字何时加入或离开它。
  • 套接字不加入或离开房间。客户加入或离开房间。我认为您对客户(不是您)感兴趣,那么?
  • 我不认为你理解这个问题。没有“我”……这是服务器端代码。根据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'); });
  • 啊。所以“房间”是一个低级的东西,有点像多播组,而不是聊天室。

标签: javascript node.js socket.io


【解决方案1】:

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

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

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

【讨论】:

  • 这不是我要找的。我想为套接字join()leave() 房间未完全连接或断开服务器时创建事件处理程序(尽管断开应该会导致"leave" 事件)。
  • @camupod - 套接字不知道“房间”。 Room 是一个应用程序级别的概念,因此套接字永远不会加入或离开房间。您必须编写一些更高级别的处理程序来自己发出加入和离开事件。
  • @StephenP - 套接字不需要知道房间。我想知道“房间”(io.sockets.in('name'))是否有可能告诉我什么时候加入或离开。
【解决方案2】:

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

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

【讨论】:

  • a room isn't a "thing" as much as it's a "filter" -- 这就是我所担心的(我希望 socket.io 有更好的文档)。我想我必须编写自己的房间版本...谢谢!
  • 我对 join 处理程序的参数有疑问 - stackoverflow.com/q/16969463/37759
【解决方案3】:

我知道这个问题很老,但是对于通过谷歌搜索偶然发现这个问题的人来说,这就是我处理它的方式。

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

/* 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

我希望这可以从我的研究和测试中为其他人指明正确的方向。

【讨论】:

  • 非常感谢,这正是我想要的!我不知道“断开连接”和“断开连接”之间有区别,这就是为什么我没有在“断开连接”时获得 roomId。
【解决方案4】:

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

关键是不要使用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();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-10
    • 2016-04-26
    • 1970-01-01
    • 1970-01-01
    • 2012-07-08
    相关资源
    最近更新 更多