2015-10-05 2 views
1

Я пишу простую программу chat.io (v1.3.6). Когда пользователи регистрируются с их именем пользователя, они могут видеть несколько комнат для бесед на приборной панели и вводить каждый из них через разные конечные точки, т. Е.Socket.IO - как получить разные активные списки пользователей для разных конечных точек/комнат?

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

Пользователи могут общаться в любом из этих номеров. Для каждой комнаты я хотел бы создать активный список пользователей. «active» означает, что этот пользователь теперь подключен к сокету (в чате в этой комнате).

Я вижу, что многие вопросы были опубликованы, но все еще смущены их несколькими изолированными словами.

В моем нынешнем 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, которые могут отличаться для одного и того же пользователя?

Большое спасибо.

Update:

Мой код на стороне сервера:

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

это хорошо работает. Не могли бы вы рассказать мне, почему?

ответ

3

Как я могу различить разъемы для разных номеров/конечных точек?

На вашем сервере есть несколько способов перечислить различные комнаты и розетки в каждой комнате. Вот некоторая информация о различных данных, которые вы можете получить доступ на сервер, а затем вы можете решить, что является наиболее эффективным способом, чтобы получить то, что вы хотите:

io.sockets.adapter.rooms

Это объект, содержащий все номера, ключи, в настоящее время имеют по крайней мере одно соединение в них. Это содержит обе комнаты, на ваш сервер .join(), для ручного подключения сокета к комнате и содержит каждую комнату по умолчанию (с именем socket.id), с которой каждый сокет автоматически соединяется.Итак, если вы знаете, что у вас есть комната по имени "test", то вы можете получить объект с каждой комнатой в виде ключей с io.sockets.adapter.rooms['test'].

io.sockets.connected

Это объект, содержащий каждый сокет, который в данный момент подключен, где socket.id является ключевым в объекте. Итак, если id vlPYz3EHUOe8vFitAAAJ, то вы можете получить доступ к объекту сокета для этого идентификатора как io.sockets.connected['vlPYz3EHUOe8vFitAAAJ']. Вы можете, очевидно, перебрать все подключенные сокеты, используя петлю типа for (var sock in io.sockets.connected). Затем внутри этого объекта сокета вы можете увидеть, в каких комнатах он находится через: io.sockets.connected['vlPYz3EHUOe8vFitAAAJ'].rooms, который представляет собой массив имен комнат, в которых он находится. Этот массив имен комнат будет включать автоматическую комнату с тем же именем, что и socket.id.

io.sockets.sockets

Это массив связанных сокетов и, возможно, более простой способ получить доступ ко всем подключенных в данный момент сокетов, чем при использовании io.sockets.connected. Как описано в предыдущем разделе, когда у вас есть данный подключенный сокет, вы можете получить доступ к свойству socket.rooms, чтобы получить массив комнат, в которых в данный момент находится сокет.

Для конкретного сокета вы можете получить список комнат, в через:.

socket.rooms 

, который представляет собой массив имен номеров, что данный сокет в настоящее время в этом включает в себя автоматическое имя номер одного и то же имя, как socket.id, так что вы можете захотеть игнорировать это имя комнаты, если просто попробовав перечислить обычные комнаты, в которых есть гнездо.

Как я могу получить активные имена пользователей вместо socket.id, которые могут быть разными для одного и того же пользователя?

Поскольку имена пользователей - это то, что вы назначили и не имеете никакого отношения к socket.io, в частности, вам нужно будет найти способ связать имя пользователя с самим сокетом. В зависимости от того, где имя пользователя известно, вы можете сделать это в разных местах. Если он уже присутствует в файле 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); 
    }); 

}); 
+0

Большое спасибо @ jfriend00 это идеальный ответ! – leonsPAPA

+0

Я попытался использовать этот код и получил ошибку, поэтому я разместил здесь новый вопрос. Http://stackoverflow.com/questions/35249324/typeerror-list-foreach-is-not-a-function-in-socket-io – Mojtaba

+0

@Mojtaba - Какая версия socket.io вы используете, потому что ваш выше код работает отлично для меня в моем собственном тестовом приложении, используя socket.io 1.3.6? – jfriend00

Смежные вопросы