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.
Related
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.
I want to listen for the event in which a user leaves a room. From what I've researched, socket.rooms apparently contains the rooms that a socket is in. However, when I listen for the disconnect event from a socket, apparently the socket left the room prior to disconnect. Therefore, socket.rooms will yield an empty object after the disconnect event. I need to listen specifically for the event in which a user leaves a room, not the socket disconnect event, since I have an array of room objects and wish to delete the user from the room when they leave.
A user cannot leave a room without your server removing them from the room or when the user disconnects. Clients cannot leave a room on their own. So, to know when a user leaves a room, you just need to hook into your own code that removes them from a room and also listen for the disconnect event.
Other than a disconnect, the only other way a user can leave a room is if your own code removes them from a room so you can just hook into that specific function and trigger the update of your own data structures when your own code removes them from the chat room.
For the disconnect event, if you are maintaining your own room data structures, then you can just remove a given socket from any room that you find it in when you get the disconnect event (e.g. search each room and remove it from any room that you find that socket in).
i have a problem over implementing sockets. Case:
the user has n number of rooms in his list,
user should be able to receive notifications from each of the rooms.
method 1) open a socket for each room user has. in this user has to open multiple sockets for each room
method 2) users opens a single socket with room name = userid,
node maintains a list ('room_user') of each room and users in that room (this can be done on connection).
eg
room_user:{
room1 : {
user1Id, user2Id
}
room2 : {
user1Id, user3Id
}
}
For sending a message the server gets the userid's from the list for a specified room and then emits the message in a loop to all users. In this approach the user has to open only one socket but the server has to emit the same message in a loop
i want to know which method would be better suited
If you consider the underlaying TCP/IP broadcast system, you would probably find that it is better that the user have a single websocket connection and the server loop and send the same message again and again (method 2 in your question).
Allow me to explain:
TCP/IP doesn't support broadcasting. For this reason, sending the same message to multiple connections is actually implemented by looping over the list of connections and sending the same message again and again...
It's true that your code will be moving the loop to a higher level of the application, but it would probably be better than having many connections that would hinder your ability to scale the application.
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
}
I am running a node.js server with socket.io 0.9. (xhr-polling)
I tried to simulate 300 clients connected to one big room.
I noticed that when I emit one single message to all members in the room, about 40-50 people in the room will be disconnected!
Syntax to emit message to everyone in the room:
io.sockets.in(roomId).emit("abc", "efg");
It is fine if I reduce the number of clients in the room to 100. Emit messages to room won't disconnect them.
This is definitely not acceptable. What is happening?