Socket.IO - 如何为不同的端点/房间获取不同的活动用户列表? [英] Socket.IO - how to get different active user lists for different endpoints/rooms?

查看:14
本文介绍了Socket.IO - 如何为不同的端点/房间获取不同的活动用户列表?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个简单的基于 socket.io(v1.3.6) 的聊天程序.当用户使用他们的用户名登录时,他们可以在仪表板中看到几个聊天室,并通过不同的终端输入每个聊天室,即

I am writing a simple socket.io(v1.3.6)-based chatting program. When users log in with their username, they could see several chatting rooms in dashboard and enter each of them via different end ponts, i.e,

http://localhost:8080/api/chats/room01.

用户可以在这些房间中的任何一个聊天.对于每个房间,我想创建一个活动用户列表.'active' 表示该用户现在已连接到套接字(在此房间聊天).

Users could chat in any one of these rooms. For each room, I would like to create an active user list. 'active' means this user is now connected to socket (chatting in this room).

我看到很多问题已经发布,但仍然被他们几个孤立的词弄糊涂了.

I see many questions have been posted but still confused by their few isolated words.

在我当前的 server.js 中,我添加了以下代码:

In my current server.js, I added this code:

var io = require('socket.io')(http);

io.on('connection', function(socket){

  console.log('a user connected: ' + socket.id);

  socket.on('disconnect', function(){
    console.log(socket.id + ' has disconnected from the chat.');
  });

});

总结一下,两个问题:

  • 如何区分不同房间/端点的socket连接?

  • How can I distinguish the socket connections for different rooms/endpoints?

我怎样才能获得活跃的用户名而不是 socket.id ,这对于同一用户来说可能不同?

How can I get active usenames instead of socket.id which could be different for the same user?

非常感谢.

更新:

我的服务器端代码:

io.of('/rooms/room01').on('connection', function(socket) {

  console.log("socket connected: ", socket.id);
  //....some more codes

});

我的客户端代码:

app.factory('socketio', ['$rootScope', function($rootScope) {
  'use strict';

  var socket = io.connect('http://localhost:8080/rooms/room01');
  return {

    on: function(eventName, callback) {
      socket.on(eventName, function() {
        var args = arguments;
        $rootScope.$apply(function() {
          callback.apply(socket, args);
        });
      });
    },

    emit: function(eventName, data, callback) {
      socket.emit(eventName, data, function() {
        var args = arguments;
        $rootScope.$apply(function() {
          if (callback) {
            callback.apply(socket, args);
          }
        });
      });
    }
  };
}]);

上面的代码不起作用.但是以前当我使用默认命名空间时

The above code does not work. But previously when I use the default namespace

io.of('/').on('connection', function(socket) {
  //...
}

var socket = io.connect('http://localhost:8080/');

效果很好.你能告诉我为什么吗?

it works well. Could you pls let me know why?

推荐答案

如何区分不同的socket连接房间/端点?

How can I distinguish the socket connections for different rooms/endpoints?

在您的服务器上,有几种方法可以列出每个房间中的各个房间和插座.以下是有关您可以在服务器上访问的各种数据的一些信息,然后您可以决定哪种方式是获得所需数据的最有效方式:

On your server, there are a couple ways to list the various rooms and sockets in each room. Here's some info about the various data you can access on the server and you can then decide which is the most efficient way to get what you want:

io.sockets.adapter.rooms

这是一个包含所有房间作为键的对象,其中当前至少有一个连接.这包含您的服务器称为 .join() 的两个房间,用于手动将套接字加入房间,并包含每个套接字自动加入的每个默认房间(具有 socket.id 的名称).因此,如果您知道自己有一个名为 "test" 的房间,那么您可以使用 io.sockets.adapter.rooms['test'].

This is a object containing all the rooms as keys that currently have at least one connection in them. This contains both rooms your server called .join() for to manually join a socket to a room and contains each default room (with the name of the socket.id) that each socket is automatically joined to. So, if you know you have a room by the name of "test", then you can get an object with each room as keys with io.sockets.adapter.rooms['test'].

io.sockets.connected

这是一个包含当前连接的每个套接字的对象,其中 socket.id 是对象中的键.因此,如果 id 是 vlPYz3EHUOe8vFitAAAJ,那么您可以访问该 id 的套接字对象作为 io.sockets.connected['vlPYz3EHUOe8vFitAAAJ'].您显然可以通过使用 for (var sock in io.sockets.connected) 类型的循环来迭代所有连接的套接字.然后,在该套接字对象中,您可以通过以下方式查看它位于哪个房间:io.sockets.connected['vlPYz3EHUOe8vFitAAAJ'].rooms 这是它所在的房间名称数组.这个数组房间名称将包括与 socket.id 同名的自动房间.

This is an object containing each socket that is currently connected where the socket.id is the key in the object. So, if the id is vlPYz3EHUOe8vFitAAAJ, then you can access the socket object for that id as io.sockets.connected['vlPYz3EHUOe8vFitAAAJ']. You can obviously iterate all connected sockets by using a for (var sock in io.sockets.connected) type of loop. Then, inside that socket object, you can see which rooms it is in via: io.sockets.connected['vlPYz3EHUOe8vFitAAAJ'].rooms which is an array of room names it is in. This array of room names will include the automatic room of the same name as the socket.id.

io.sockets.sockets

这是一个已连接套接字的数组,与使用 io.sockets.connected 相比,它可能是访问所有当前连接的套接字更简单的方法.就像上一节中描述的那样,一旦你有了一个给定的连接套接字,你就可以访问 socket.rooms 属性来获取套接字当前所在的房间数组.

This is an array of connected sockets and is perhaps an easier way to access all the currently connected sockets than using io.sockets.connected. Like described in the previous section once you have a given connected socket, you can access the socket.rooms property to get an array of rooms that socket is currently in.

对于特定的套接字,您可以通过以下方式获取它所在的房间列表:

For a specific socket, you can get a list of rooms that it is in via:

socket.rooms

这是给定套接字当前所在房间名称的数组.这包括与 socket.id 同名的自动房间名称,因此您可能希望忽略该房间名称如果只是想列出插座所在的常规房间.

which is an array of the room names that a given socket is currently in. This includes the automatic room name of the same name as the socket.id so you may want to ignore that room name if just trying to list the regular rooms that a socket is in.

我怎样才能得到活跃的用户名而不是 socket.id 可能是同一用户的不同?

How can I get active usenames instead of socket.id which could be different for the same user?

因为用户名是你分配的东西,特别是与socket.io无关,你必须自己找到一种方法将用户名与套接字相关联.根据用户名的已知位置,您可以在不同的位置执行此操作.如果它已经存在于 cookie 中,那么您可以从以下位置获取它: socket.handshake.headers.cookie 这是在该套接字出现时为该特定套接字设置的 cookie 的快照最初连接.

Since usernames are something you assigned and have nothing to do with socket.io in particularly, you will have to find a way to associate the username with the socket yourself. Depending upon where the username is known, you can do that in different places. If it is already present in a cookie, then you can fetch it from: socket.handshake.headers.cookie which is a snapshot of the cookies that were set for this particular socket at the time the socket was initially connected.

如果在最初连接套接字时以其他方式知道用户名,您可以从其他机制中获取它并将其保存为套接字对象的属性:socket.username = 'xxx'; 然后你可以随时从服务器端的socket对象访问它.

If the username is known some other way at the time that the socket is initially connected, you can grab it from that other mechanism and save it as a property of the socket object: socket.username = 'xxx'; and then you can access it from the server-side socket object at any time.

这是我用来探索这些不同数据结构的一些服务器端诊断代码:

Here's some server-side diagnostic code that I've used to explore these various data structures:

'use strict';
var express = require('express');
var app = express();
var server = app.listen(80);
var io = require('socket.io')(server);
app.use(express.static('public'));

io.on('connection', function(socket) {
    console.log("socket connected: ", socket.id);

    // list all connected sockets
    var list = io.sockets.sockets;
    console.log("Connected sockets:");
    list.forEach(function(s) {
        console.log("    socket.id = ", s.id);
    });

    socket.on('join', function(name) {
        socket.join(name);

        // list all rooms
        console.log("Active rooms:");
        var rooms = io.sockets.adapter.rooms;
        for (var room in rooms) {
            if (rooms.hasOwnProperty(room)) {
                console.log("     ", room);
            }
        }

        // list all rooms this socket is in:
        console.log("Active rooms for this socket:");
        io.sockets.connected[socket.id].rooms.forEach(function(room) {
            console.log("    ", room);
        });


    });

    socket.on('leave', function(name) {
        socket.leave(name);
    });

});

这篇关于Socket.IO - 如何为不同的端点/房间获取不同的活动用户列表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆