我想做类似的事情:
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
});
答案 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#id
和random-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');
});