Socket.io: Send message to a specific namespace with specific ID - node.js

Is it possible to send a message to a socket with different namespace using their custom socket.id??. I'm using socket.io to create a chat and send private message.
I successfully manage to create a room and send a message to each other privately using
io.to(room).emit('chatMessage', from, message);
But I also want to send a message to sockets with different namespace using their ID like:
io.of('nameSpace').to(socket.id).emit('chatMessage', from, message);
I've tried different combination such as,
io.of('nameSpace').to(socket.id).emit('chatMessage', from, message);
io.of('nameSpace).sockets.socket(socket.id).emit('chatMessage', from, message);
io.to(users[socketid]).emit('chatMessage', from, message);
io.sockets.socket(socketid).emit('chatMessage', from, message);
but it's not working. Is there other way to send a message to a specific client with different namespace? I'm using a combination of rooms and namespace.
NOTE: I'm using the string query that's equal to the name of the user as the name of my room.

This solution works for multiple namespaces.
Assume we have two namespaces:
/v1
/v2, Socket ID: LOchCx6DZ8YwPVF8AAAv
Syntax for emitting a message from namespace-1 to namespace-2 is
io.of('/v2').to('/v2#LOchCx6DZ8YwPVF8AAAv').emit('message', 'Hello');

Related

io.to(targetSocketID).emit() is there a way to emit to just sender and receiver

I'm trying to create a private messaging functionality using socket.io with React and Node.
I am able to send a message to a particular socket like so:
io.to(targetSocketID).emit('privateMessage' message)
it successfully sends it to that specific user but not the sender. is there a way to just emit a message to sender and the target user to make this simple? From what I can see there is two approaches here.
When a message is created push the sender messages into a messages array setMessages([...messages, senderMessages]) and also push the socket message into that array setMessages([...messages, receivedMessages]). this approach seems sloppy and like to avoid this route as it can become problematic.
generate a unique room for each user and send the room to the server and join it:
//server
socket.on('joinRoom', room => {
socket.join(room)
socket.on('privateMessage', message => {
socket.on(room).emit('messageResponse', message)
})
})
I would like to know if there is a better way to do this.
that allows me to emit a message to just sender AND targeted receiver.

Socket Io users Connected to two rooms gets messages from both rooms in same window

I am trying to achieve the same feature as groups, where a user is connected to more than one room at a time.
Let's imagine two users 1 and 2, respectively connected to the rooms A and B. When I do socket.broadcast.to(A).emit, both users are getting the message on the same window, even though both of them are connected to different rooms
I get groupsList the user is connected from database. I am using the groupId
for(var i=0;i<groupsList.length;i++){
var groupName = groupsList[i].Id.toString();
socket.join(groupName);
}
Message form Client side is sent using
socket.emit('send-Group-Message', {msg:messageBox.val(),"groupId":$("#connectedGroup").val()});
On the server Side
socket.on('send-Group-Message',function(data){
socket.broadcast.to(groupIdString).emit('group_message',{msg:message,date:Datesent,senderUsername:socket.nickname,senderDisplayName:displayName})
socket.emit('myGroup_message',{msg:message,date:Datesent,senderDisplayName:displayName});
});
then on the client side
socket.on('group_message', function (data) {
chat.append("<div class=\"row\" ><span class='recivedMessage'><div class=\"alert alert-info textWrap\"><b>"+data.senderDisplayName+": </b>"
+ data.msg + "<br><span class=\"date\">"+ data.date.toString() +"</span></div></span></div>");
});
I can check which group is associated to the message from the client side, but I am not sure if this is the right method.
How can I cleanly separate the rooms?
If a socket can be in more than one room in your app and you want the receiving client to know which room a message was from, then you need to include the room that the message pertains to in your message broadcast:
socket.broadcast.to(A).emit("newMsg", {room: A, msg: "some Message Here"});
Then, the receiving client gets both the message data and a room name that it corresponds to and the client can then display that message in the corresponding widget on the page that is appropriate for that room.
The broadcast, by itself, does not indicate the room it was broadcast to. A room is really just a server-side concept for grouping sockets. When it goes to broadcast to the room, it literally just gets a list of sockets, iterates through each socket in the list sending the desired message. There is no concept of the room actually sent with the message. So, as I said above, if you want the receiver to know the room a message corresponds to, then you need to explicitly send it with the message.

Is there an alternate way of sending a private message with Socket.io (1.0+)?

Im working on a simple session based app shared by a session code in the URL. I decided to generate and assign a shorter user friendly unique ID for each client who connects to a socket, and the client who creates a session causes a socket.io room to be created with his ID.
I didnt realize until later that the private messaging mechanism in socket.io relied on each client being assigned to a room named by their ID. This means that because my room for a session is named after the creator's socket ID, using .to() will not message that client, but rather all of the clients now assigned to that room.
I could remedy this in ways that would require some re-design, but first I wanted to ask if there is an alternate way of sending a message to a specific client via his/her ID.
/*create an array of clients, where key is the name of user and value is its unique socket id(generated by socket only, you do not have to generate it) during connection.*/
var clients = {};
clients[data.username] = {
"socket": socket.id
};
//on server side
socket.on('private-message', function(data){
io.sockets.connected[clients[data.username].socket].emit("add- message", data);
});
//on client side
socket.emit("private-message", {
"username": userName,
"content": $(this).find("textarea").val()
});
socket.on("add-message", function(data){
notifyMe(data.content,data.username);
});

Nodjs How to broadcast message to namespace with room

I am able to send the message to particular namespace room with the following code
io.of(namespace).in(room).emit('functionname', data);
but it sending to all the connected client including the sender, what I want is I want to send the message excluding the sender, I have tried with following method but everything failed since syntax is not correct
io.broadcast.of(namespace).in(room).emit('functionname', data);
io.of(namespace).broadcast.in(room).emit('functionname', data);
io.of(namespace).in(room).broadcast.emit('functionname', data);
io.of(namespace).in(room).broadcast('functionname', data);
How can I send the message to every client excluding the sender.
I believe what you want is along the lines of this:
// send to all clients except sender
socket.broadcast.emit('event', "this is a test");
// send to all clients in 'room' room except sender
socket.broadcast.to('room').emit('event', 'whadup');
// sending to all clients in 'room' room, include sender
io.sockets.in('room').emit('event', 'woodup');
You can add the "of.(namespace)" if you wish to specify the namespace as well.
Do this to send a message to everyone except the sender:
socket.broadcast.emit('event', "this is a test");
i have got that problem. io.of() confused me.
when you used 'connection' as io.of(),
your socket already got namespace. so you just add particular room.
io.of(namespace).in(room).emit('functionname', data);
-> sokcet.broadcast.emit('event',data);
I was having trouble with this too.
The key is to use
socket and not io
This will NOT work:
io.of(namespace).broadcast.to(room).emit('event', data)
However, this will work:
socket.to(room).emit('event', data)
One drawback though is that this will only work if the socket you are sending from is in the namespace you want to send to. If you want to send to a different namespace, I don't think this approach would work

Socket.IO define namespace in runtime

In socket.IO there are 2 ways to send message to users separately: rooms and namespaces. In my project I need both of them - namespaces to divide users of different applications and rooms for each namespace for private messages and other specific stuff.
It's quite easy to create rooms directly in runtime. But is it possible to do the same trick with namespaces? I'd like to do something like this:
io.of(*someFunctionToCreateNameSpaceInRuntime*)
.on('connection', function (socket) {
socket.emit(***);
});
There is very similar question, but id doesn't work now. Is it possible to send namespace name with params and store it somewhere before connection event fires?
Thanks for any advise.

Resources