Socket.IO – 如何为不同的端点/房间获取不同的活动用户列表?

我正在写一个简单的socket.io(v1.3.6)的聊天程序。 当用户用他们的用户名login时,他们可以在仪表板上看到几个聊天室,并通过不同的terminal字体input每个聊天室,

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

用户可以在任何一个房间聊天。 对于每个房间,我想创build一个活跃的用户列表。 “主动”意味着这个用户现在连接到套接字(在这个房间聊天)。

我看到很多问题已经发布,但仍然被他们几个孤立的单词混淆。

在我目前的server.js中,我添加了这个代码:

 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.id ,这可能是不同的同一个用户?

非常感谢。

更新

我的服务器端代码:

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

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

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

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

它运作良好。 你能告诉我为什么吗?

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

在您的服务器上,有几种方法可以列出每个房间的各种房间和sockets。 以下是关于您可以在服务器上访问的各种数据的一些信息,然后您可以决定哪一种是最有效的方式来获得您想要的:

io.sockets.adapter.rooms

这是一个包含所有房间的对象,当前键中至less有一个连接。 这包含两个房间你的服务器调用.join()手动join到一个房间的套接字,并包含每个套接字自动join到每个默认房间(与socket.id的名称)。 所以,如果你知道你有一个名为"test"的房间,那么你可以通过io.sockets.adapter.rooms['test']每个房间的对象作为关键字。

io.sockets.connected

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

io.sockets.sockets

这是一个连接套接字的数组,可能比使用io.sockets.connected更容易访问所有当前连接的套接字。 一旦您有一个给定的连接套接字,就像上一节所述,您可以访问socket.rooms属性来获取套接字当前所在的一组房间。

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

 socket.rooms 

它是给定套接字当前所在的房间名称的数组。这包括与套接字socket.id相同名称的自动房间名称,所以如果您只想列出常规房间,那么您可能需要忽略该房间名称sockets在。

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

由于用户名是你分配的东西,并且与socket.io没有任何关系,所以你必须find一种方法将用户名和套接字自己关联起来。 根据用户名在哪里知道,你可以在不同的地方做到这一点。 如果它已经存在于一个cookie中,那么你可以从socket.handshake.headers.cookie获取它,它是在套接字最初连接时为这个特定套接字设置的cookie的快照。

如果在套接字初始连接的时候用户名已知,你可以从另一个机制中获取,并保存为套接字对象的属性: socket.username = 'xxx'; 然后您可以随时从服务器端套接字对象访问它。

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

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