Nodjs How to broadcast message to namespace with room - node.js

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

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 send messges to only some users in room

I want to send message in a room using socket.io but i some cases i want to skip some users in room so how can i do that.
Currently i am using below code to send message in group
io.on('connection', function (socket) {
sockets[socket.handshake.query.id]=socket;
console.log("user_connect",socket.handshake.query );
if(socket.handshake.query.user_type=="DRIVER"){
socket.join('orderPool');
}
socket.join('USER_'+socket.handshake.query.id);
socket.on('disconnect', function () {
delete sockets[socket.handshake.query.id];
console.log('user disconnected', socket.handshake.query.id);
});
});
io.sockets.in("ROOMNAME").emit("POOL_EVENT_RECIEVED", data);
One solution is to simultaneously keep another room "<room name>-selected users" with only selected users you want to send the messages. Don't add to this room the users you want to skip.
So, when you send messages to this room, users who weren't added to this room won't receive those messages.
sometimes io disconnected and try to reconnect again but I think it's not your problem.
Note that you can emit to rooms that exists in particular namespace. if you use default namespace '/' so try it:
io.of('/').in("ROOMNAME").emit("POOL_EVENT_RECIEVED", data);
also you can read socket.io emit cheatsheet: https://socket.io/docs/emit-cheatsheet/

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

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

How to send personal messages using socket io and node express

im implementing a chat system where you can send personal messages to a particular person connected to a shocket.
first im putting the username as a key along with the shocket.id to a jason called "connectedUser".
socket.username=loggeduser;
connectedUser[socket.username]=socket.id;
Then im using this code send a personal message
socket.broadcast.to(connectedUser[usersnametobesent]).emit('chat', { message:result});
this works perfectly but whenever i use this it only shows the message on receiver's side but not the clients. i need it to be shown in both sender and receiver's side.
You will need to emit the same thing to the sender.
socket.emit('chat', {});
That function will only send to just that socket.
Why not just use some DOM manipulation to add the chat message to the clients side. This will also add a better user experience for if say there was bad lag for whatever reason, your sender would see the message he sent instantly and not rely on waiting to see his message return from the socket?
Here is a nice little cheat sheet for sockets:
// sending to sender-client only
socket.emit('message', "this is a test");
// sending to all clients, include sender
io.emit('message', "this is a test");
// sending to all clients except sender
socket.broadcast.emit('message', "this is a test");
// sending to all clients in 'game' room(channel) except sender
socket.broadcast.to('game').emit('message', 'nice game');
// sending to all clients in 'game' room(channel), include sender
io.in('game').emit('message', 'cool game');
// sending to sender client, only if they are in 'game' room(channel)
socket.to('game').emit('message', 'enjoy the game');
// sending to all clients in namespace 'myNamespace', include sender
io.of('myNamespace').emit('message', 'gg');
// sending to individual socketid
socket.broadcast.to(socketid).emit('message', 'for your eyes only');
Credit to https://stackoverflow.com/a/10099325
To answer your comment:
In the case of sockets, if you're sending a chat message say from a client so we got client1 and client2
Assuming you have a chat window you probably have some divs and maybe some lists like ul
Client1 sends to Client2 ---> "Hello"
Client1 should immediately see the message "Hello" by using simple Dom stuff like creating a new div / li and appending it to the chat window maybe with some sort of ID to keep track of messages.
Then if the message fails to send you can find that message by id that failed, remove it and maybe append an error message instead that says whatever, message failed to send.
Meanwhile client2 is none the wiser a message had ever been sent
If you use sockets to populate messages for both users then you might run into a case where
Client1 sends to Client2 ----> "Hello"
Now maybe your server has a hiccup or the client lost connection for a second for whatever reason, he doesn't see his message yet and goes oh maybe it didn't send so he goes
Client1 sends to Client2 ----> "Hello"
Client1 sends to Client2 ----> "Hello"
Client1 sends to Client2 ----> "Hello"
Still nothing, he does it 20 more times.
Suddenly the server or whatever unlocks and sends 300 hello messages both clients are spammed.
Sorry for formatting I'm on mobile.
Simply,
This is what you need :
io.to(socket.id).emit("event", data);
whenever a user joined to the server,socket details will be generated including ID.This is the ID really helps to send a message to particular people.
first we need to store all the socket.ids in array,
var people={};
people[name] = socket.id;
here name is the reciever name. Example:
people["ccccc"]=2387423cjhgfwerwer23;
So, now we can get that socket.id with the reciever name whenever we are sending message:
for this we need to know the recievername.You need to emit reciever name to the server.
final thing is:
socket.on('chat message', function(data){
io.to(people[data.reciever]).emit('chat message', data.msg);
});
Hope this works well for you.!!Good Luck

Edit message in socket.io before it is sent to the user

I'd like to intercept certain messages being sent in the receiver point of view. This means, for example:
SENDER SIDE
User sends message
Server receives message
Message could be treated here but I don't want to work it here
RECEIVER SIDE
I want to treat it in the server before being emit
Message is emit
User receives message (for example, in browser) with socket.on('message',(...));
Does anyone have any idea which part of the code needs to be changed in socket.io to accomplish that? I've been searching the modules: adapter, client, parser... but found nothing relevant... Any thoughts on this one? I've been getting a bit desperate xp
server side:
socket.on("chat", clientMsg);
function clientMsg(data){
console.log("data received:" + data)
var msg = data; // set the msg to be sent
// treat the data server side or
// if wanting to treat the data from the user's side
// create another socket.on() inside this function. to treat it remotely (if needed)
// then, when finished send the message to all users with the treated data.
io.sockets.emit("chat", msg)
};

Resources