socket.io chat with private rooms - node.js

I started looking into node and socket.io.
I already have created a simple chat application and I am amazed at how easy it was.
Now, I would like to take a little bit further and provide a list of online users that have the ability to chat with each other in private.
What would be the best way to approach this?
I read on 0.7's new room feature. Would that be a way to go? Dynamically create a new room each time 2 users need to chat in private? But how the second user is going to be notified of the new room created, so that he can connect there?
Is it better to handle all the above logic myself? Store the rooms and users server side and loop through them each time and send messages to the appropriate ones?
Thanks

If the only functionality you want is for two people to be able to send messages to one another (and not groups of people to have a room), then the logic could be something like this:
When a user connects, store their connection in an object keyed by their username (or in any other data structure that ensures you can find a specific user's connection).
When a Bob wants to talk to Jeff, send the server an event stating such.
The server looks up Jeff's Socket.IO connection in the object from step 1.
The server uses this connection to send Jeff (and only Jeff) the private message.

Hej Thomas
if theres only 2 users talking you dont need use publish att all just send that message from the client to the server and let the server locate the other client and send it down.

Related

Sending private message to user with socket.io

I am trying to implement private messaging with socket.io for my mobile applications which have a direct messaging feature like Instagram. Right now, I am using Node.js and React Native. I am kinda new to socket.io. I saw many examples of that. However, one thing is not clear in my mind.
User clicks "send message" button. Then I create a socket connection and the user joins a room with socket id. Then user sends a message to that room.
The problem here is, how other user will get the message? Because at this point, I don't think other user knows the room id. Of course if there is a better solution for that, I am open to every suggestion.
One thing you can do is create a room for each person. When the person logs into your app and connects with socket.io, you'll want to have them automatically join the room with their user id.
Then when someone wants to send them a message, they can just send the message to the room for the receiving user.
However, I think if you are building a messaging app, socket.io is not the right way to go. As far as I know you can't listen on sockets while the app is in the background (and even if you could, it would drain your users' battery life). You should use push notifications instead and use the data field (e.g. zo0r/react-native-push-notification and firebase).

How can I securely implement a notification system using socket?

I am currently working on a web application using the MEAN stack. It has a social aspect to it so I want to be able to push notifications to users.
The way I do it now is when something happens that should be a notification it gets stored in a mongo database with an unread flag. Each client will send a get request to the server every 30 second and will receive every notification marked as unread, and will then mark it as read.
I want to switch to using a message queue and sockets so less network resources will be used, and also provide the user with a real-time experience. I've thought about using redis and its pubsub structure but I can't seem to figure out how to do this securely. If I push out notifications to the affected users, won't it be easy for someone malicious to subscribe to somebody else's channel and receive notifications not meant for them? Am I missing something or is it just the wrong approach for such a system?
Edit: Figure I update with the solution I went with if anyone else reading this is having the same problem.
Instead of using rabbitmq, as the answer suggested, I figured that a much more easy and elegant solution is to just use socket.io. When new sockets connects to the server I save a mapping from the userID to the socketId in a redis in-memory DB. (After I've validated their token) That way, if I need to push a notification to a user I just look up the socketId in the redis DB, and then send it to the correct socket.
This way I don't need any security beyond that as socketIDs are unguessable, and the message is only sent across the single socket that belongs to the given user.
This way it will only get sent through the connection of the given socket, as socketIDs are only used server side to keep track of all the connection. This means no one else can "listen" using someone else's socketID.
you can use RabbitMQ for this. Also authentication is there. Please go through following link and try.
https://www.rabbitmq.com/access-control.html
also, you can apply authentication in existing structure using subscription auth tokens with all subscribed users only.
even redis has its security with topics. Please have a look in link below
https://redis.io/topics/security

How to use socket.io-redis Nodejs

Good afternoon,
I have a chat application written with NodeJS, Express and socket.io, in that application there are no rooms, when a user connects the socket (connection of that user) is linked to his id in an object that stays in memory:
Users = {
'1': {socket},
'2': {socket},
...
}
This works great! When a user is going to send a message it informs the recipient's id the server retrieves the equivalent socket and sends the message.
My problem is that due to the number of users I will have to upload a new server with the application, the problem is that users on different servers can not communicate because each server knows only the list of users that is connected to it. After much reading I came to the conclusion that the best way to solve this is by using the Redis Adapter, I looked for examples on the internet exhaustively however they all use Rooms to send the messages or send the same message to all the user and I would like to send one Message to a specific user regardless of which server instance it is if possible without the need to create rooms, simply recovering its connection based on its id and sending the message, would like to know if someone could tell me if this is possible and how to implement.
Below is an image of how my architecture should look:

Efficient Chat Streams

I'm attempting to create an application which will work as a chat app. I'm currently contemplating the best way to do this and I'm thinking of going with a server sent event package such as the following. Every conversation would have an id, and the message would be emitted under the id. For instance
stream.emit(1512, "Hello") would send the message and
stream.on(1512, function(message){console.log(message)}) would print the message. Only the chat members would have the chatId.
I was initially thinking of using websockets but I thought that not every user should be receiving data, as chats were private and I didn't want to configure authentication within websockets.
Back to server sent events:
I have a few questions on the topic.
Are they efficient and, if not, what would be a more efficient solution
Is the method of sending chat through a randomized, hashed, id (such as 309ECC489C12D6EB4CC40F50C902F2B4D) secure?
Would you recommend a different method for sending chat? This is to be implemented as a mobile application where individual users can chat privately with oneanother so, again, security is pretty important.
Thanks.
I recommend the client-call package (disclaimer: I wrote it). It provides a very simple method to run a client-side method from the server code.
Besides this, you can always just put the chat messages to a db collection and remove them after some time.

push notification like facebook

i want to build a push notifications service like facebook with nodejs and socketio. i have a question:
- how server can know what exactly client to send notification when many client connected to server?
Thanks for help!
Associate sockets with users when they connect, so when you have to notify user "Test" just look at the user.sockets[] list and send him whatever info you want to send.
In other words, Node.js doesn't have to "know" about users, you should take care of that and talk with Node.js in "socket" terms.
You can use socket.io's room feature. You can subscribe each client to its unique room and then emit an event in that room so that user will be the only one to get that.

Resources