Socket io creates rooms when a socket connects - node.js

Every time a socket joins a room is created in my application. Is this normal behavior?
I am not creating these rooms, as you can tell the room name is called the ID of the socket, which I find weird. Is this normal behavior?

This is normal behavior. Socket.io creates a room with the name of the connection's socket.id and automatically places only that socket in the room. This allows you to do things like:
io.to(someSocketId).emit(...)
because the socket.id is also a room name. Since socket.id values are unique and random and because all room participation is controlled by the server only, it's really just a server housekeeping thing that doesn't affect anything else.
If you have some reason to want to be able to discern which rooms are ones you created and which ones are the automatic socket.id form, you can put a unique prefix on the ones that you create such as an underscore and then you can tell which ones are yours and which ones are created by the system.
When the connection disconnects, that room will also go away.

Related

How to find the room in Which the socket is in?

I want to know the room in Which the socket is in ? I want to broadcast to the other sockets in the room during the disconnect event
If you're only ever going to have a socket in one room at a time, you can just set that room as a property on the socket object when you join it to the room. socket.currentRoom = room. Then, upon disconnect, you can just access socket.currentRoom to see what room you had it in.
It is possible to dive into internal data structures to find out what rooms a socket is in, but if you're just using one room, then the socket.currentRoom is probably easiest.

are socket io rooms automaticaly destroyed if empty?

Im starting out with node.js and socket.io.
I have 2 questions:
- When a room is empty, is it automatically destoyed unbtil recreated?
and if it is not destroyed automaticaly, does it take up much ressources on the server?
on the server side. is it the io server or the connected socket that should transmit the data?
socket.emit('doSomething');
or
io.emit('doSomething');
The room is automatically removed from the array and the nodeJSs' V8 Garbage Collector finishes the job of completely removing the room from ram. You don't have to worry about any of that. Remember that all users are automatically put on a room on joining the server ( the socket.id named room ). io.emit should be used when you want to send a message from the server to anyone and socket.emit should be used when you want to send a message only to the sender. More information can be found on this answer: https://stackoverflow.com/a/40829919/7868639

Given a user reconnects to the server (using socket.io), how can i rejoin that user to the room he belonged to?

The problem is the following:
A user connects to the server with a specific socketId, and is placed with a partner on a specific room. That room is for them two alone, and the room is not reused ever.
However, because of an internet failure, the users disconnect and then reconnect.
My question is, how do i connect the users to the room they were using in the first place when they reconnect?
Problem is when they reconnect their socketId changes, because it is creating a new connection, so i can't use that to identify them. Ip's won't work either, since more than one person can be using the site in the same household, or the same person can have two tabs open.
Thank you.
var room = user1 + user2;
socket.join(room);
io.to(room).emit('message', message);
The room can be created based on user's name, here the room is created by concatenating the user's name in ascending order. So that when user A connects to B or vice versa, they are connected to same room i.e AB.

socket.io room authorisation

I have a use case of socket.io where, within an individual namespace, a client can connect to several rooms. A user needs to authenticate on a per-room basis (because they may not be allowed to access those data streams).
Obviously I can check the authorisation on connection to the namespace using a middleware function and some auth data, but unless those rooms are already in socket.rooms when the connection is initiated, I do not know how to check, when a socket joins a room, whether or not it is authorised and subsequently force it to leave the room if it is not authorised.
Is there a join event or equivalent way of doing this? Like the connection event for a namespace but for a room.
EDIT
Having read through the source for socket.io, it appears that no events are triggered when a socket joins a room, but I might have misunderstood something: on reading the source of socket.io-client, joining rooms isn't inherent in the system, suggesting that this is only something that can be triggered on the server side. In that case, I'm assuming I have to manage the client's joining of rooms myself? If this is true, then I can just have something like:
socket.on('join', function(data) { ... });
so that when a socket wants to listen to a particular data stream, it just emits a "join" event, with some data on which room it wants to join, and I handle the whole thing on the server?
Joining a room can only be done on the server. The client typically sends an application-specific message to the server that indicates to your app that they want to join a specific room and then the server carries out that operation on the user's behalf if the request is valid.
So, all you have to do is route all your code on the server that could join a room through one particular function that can do whatever authentication you want to do. For example, you could simply create a function that was the only way your server code would ever put a socket into a room:
function joinAuth(socket, room) {
// can do anything you want here before actually joining the room
}

Can you rely on socket.id as a UID

Excuse my ignorance, day 2 of node.js/socket.io
I'm looking for a way to uniquely identify users for use in a database queuing system. I read a lot about using Express's session cookie, however I've noticed socket.id seems to be an UID that socket.io is already using.
Therefore I have been using socket.id to identify my users both in the database, and in creating private "rooms" to communicate with just them.
Is this a terrible idea?
A socket ID is just that - it uniquely identifies a socket. It doesn't uniquely identify a user, and it's definitely not intended to be used for that purpose. A single user (in many applications) might have multiple connections (and therefore multiple sockets with different ID's). Also, every time they connect they will be assigned a new ID.
So you obviously shouldn't use a socket.id as a user ID. Mustafa points out that you could reassign socket.id to a user ID, but I tend to think that's a very bad idea for two reasons:
socket.id is supposed to uniquely identify a socket, so you would run into problems when a single user has multiple sockets open.
Socket.IO, uses that ID internally a lot for storing things in hashtables, and if you change the ID, you might get unexpected results and hard to track down bugs. I haven't tested it, but looking at the Socket.IO source, that's what I would expect.
Better to generate ID's using another method then associate a user with a socket (for example, during the handshake using data from the cookie).
socket.set(key, value, callback) is the method explicitly intended to be used for associating your own data (like a user ID) with a socket connection, and is the only one guaranteed to be safe.
When the socket.io sockets are created, you can add variables as you wish to socket object. socket.userid = getUserID() will work fine. It is better to make assinging UIDs in database, and add them to socket objects when their authentication is succesful.

Resources