Android - Socket.io clients in room - node.js

Hi all :)
I need to get all clients in a room.
I have found the following code and it's works:
var clients = io.sockets.adapter.rooms['queue'].sockets;
// Output is client ID and true/false value
The issue is that I need the socket ID from each client.
clients.id or clients.socket.id ..
Does not work. Output is undifined.
Has anyone a solution for my issue ?
Second question:
Alternativ was my idea that I put all user ID's if the client is joining in a javascript array or list etc. But if I have above 500 or 1000 clients in a list .. I think that is a little bit unfavorable ?
Thanks
David

Related

NodeJS emit to specific room [socket.io]

It seems that I'm not the only one struggling with this problem.
However I am trying to write a simple chat application. When a user joins a room, the roomID is saved in socket.room.id. It is just a number.
When they join / change rooms, I have the following code:
// Notify the rooms
if(previousRoomID) io.to(previousRoomID).emit("activity-notification","<b>"+socket.me.name+"</b> has left the room " + previousRoomID);
io.to(socket.room.id).emit("activity-notification","<b>"+socket.me.name+"</b> has joined the room " + socket.room.id);
Now, Let's say that previousRoomID = 1, and socket.room.id = 30.
It sends the message, but they both seem to go to all users. If I am in roomID 1, and a user leaves the room, I get the following messages:
user has left the room 1
user has joined the room 30
I shouldnt be able to see the second message, because in the code above I am sending it to io.to(socket.room.id).emit(), yet even when I am in room 1 I am getting this message.
Strangely enough also, It seems to be using the broadcast functionality as well, even though I am not calling it; as in - it sends it to all users except the one who fired the event.
What am I doing wrong?
Okay so I have this figured out. The problem was I was calling
socket.join(roomID)
But I wasn't leaving a room first. So it turns out that a socket can join multiple rooms, which would explain why I was seeing both the messages.
if(previousRoomID) socket.leave(previousRoomID);
socket.join(roomID)
if(previousRoomID) io.to(previousRoomID).emit("activity-notification","<b>"+socket.me.name+"</b> has left the room");
io.to(socket.room.id).emit("activity-notification","<b>"+socket.me.name+"</b> has joined the room");
I dont understand the broadcast functionality though, in theory the messages should be going to everyone but for some reason the socket that calls the io.to.emit line doesnt get the activity-notification.

socket.io - io.sockets.adapter object?

I'm experimenting with socket.io and trying to build a multi-room chat app. The guide I'm following is out of date using pre 1.0.0 socket.io.
I'm trying to find a list of connected clients in a given room. Googling around shows that I have to use the adapter. However, I cannot find the documentation for it anywhere. I searched for it in the git-hub doc but search didn't return any information on adapter. https://github.com/socketio/socket.io-client/blob/master/docs/API.md
Can someone point me in the right direction and where I can read more about adapter and associated methods on it? Also if you can provide the most up to date documentation for socket.io I'd greatly appreciate it. Thank you.
You can get a map of all rooms in the top level namespace like this:
io.nsps['/'].adapter.rooms
You can list the sockets in one of those rooms like this:
function getSocketsInRoom(room, namespace = '/') {
let room = io.nsps[namespace].adapter.rooms[room];
return room.sockets;
}
As best I can tell, this kind of stuff is simply not documented. I've only discovered things like this by examining how things are stored in the debugger. That may or may not mean it's subject to change in the future - I really have no idea.
sockets:
{ '2v8OmIS4qTGX61-YAAAC': true, '3YnScxOgpmAGhZWsAAAG': true },
length: 2 }
it gives u this output. So it basically gives you the clientId and whether it is connected or not and total number of clients connected to a specific room. When the code below is executed (in server side written in node.js) gives u the above output.There is currently two clients connected to the same room named "hello".
var clientsInRoom = io.sockets.adapter.rooms[room];
but when u write this code below and console log it
var clientsInRoom = io.sockets.adapter.rooms
when single client is connected it will console log this
{ '9mVAHSDwcwnqsF4aAAAA':
Room { sockets: { '9mVAHSDwcwnqsF4aAAAA': true }, length: 1 } }
this crazy '9mVAHSDwcwnqsF4aAAAA' literals is client id which is unique for each client

Node Js, websockets save connections in channels

Hi I am using websockets with node js server, the npm module is ws. I have an array where I save all my connections but now I have to separate them so I did multidimensional array something like this:
users[channel1][user_id1] = ws_user_id1_connection
The question is when I have 1 user in multiple channels:
users[channel1][user_id1] = ws_user_id1_connection
users[channel2][user_id1] = ws_user_id1_connection
users[channel3][user_id1] = ws_user_id1_connection
From preformance point of view, is this ok?. or I can accomplish this in some other way? And if I leave it like this, Is that users[channel1],users[channel2],users[channel3], they would be only reference to the ws_user_id1_connection. I mean It's not going to add the all data about ws_user_id1_connection when I create new users[channelNew], but only reference to it. The Idea is that I would like to have something as rooms/channels and in each channel to have some connected users so they can talk each other. Is that the right way? Thank you in advance.
Assuming that channel1 is a chat room, user_id1 is the userid in the room, then yes, that's a good way to implement it, you should not create a different ws per channel. You will just need to add some information to the sent data so the client knows what is the room related to the message, something like:
{
'room': 'channel1',
'from': 'otherUser_id',
'msg': 'some text message'
}
I would recommend not to use channel to refer a room because it can be confused with a ws channel. I´d also change the name of the variable ´users´ as it is not referencing users, I´d leave it like: rooms[room_id1][user_id1] = ws_user_id1_connection
Also, you may want to check Socket.io, it is a good Nodejs library designed for that kind of applications.

socket.io How Can I Get "Socket object" list in room

folks. So far, I have been searching "How can I get socket list in room". I was able to find a lot of results.
like this link.
How to get room's clients list in socket.io 1.0
example, console.log(io.nsps['/'].adapter.rooms);
But, That answers can get the socket list in room not "Object".
I need socket object list of that into the socket in the room.
How can I get socket's object list in rooms. Please tell me solution.
io.sockets.connected[SOCKET_ID_GOES_HERE]
You can use io.nsps['/'].adapter.rooms to find socket ids and then get the objects you need with the following code:
var sockets_in_room = io.nsps['/'].adapter.rooms[ROOM_NAME_GOES_HERE]
var socket_objects = []
for (socketId in sockets_in_room) {
socket_objects.push(io.sockets.connected[socketId])
}

express.io and rooms - can i get a count of people in the room?

Express.io obviously combines socket.io and express for node.js. I'm trying however to find a way to get the # of sockets currently in a room and I can't find the right way to do it.
The code i've tried:
app.io.room('room').broadcast.length > 0
at first i thought this was the answer, but it turns out it just gives me the length of all sockets (at least i think that's what it's giving me).
or
app.io.socket.sockets.clients('room')
sockets doesn't exist on socket. I tried this one based off of the way to do it with socket.io alone.
Looking at :
getting how many people are in a chat room in socket.io
It seems like it is easy to do with socket.io, I just can't seem to find it in express.io
Edit:
I've tried:
console.log(app.io.sockets.in(room).length);
console.log(express.io.sockets.in(room).length);
first one = undefined
second one = error (Cannot call method 'in' of undefined)
This seems to work:
app.io.sockets.clients('room').length

Resources