I am wonder which way would be better to write chat application.
First idea to send message with HTTP request, save in the database, and resend message to recipient using sockets.
Second idea is to do it using only sockets.
I wonder, because I have access and refresh token authentication system with HTTP request, and I think that this way would be safer..
Either way works. Most people use sockets, but you can have a database to save logs and the such. Token authentication is usually done before entering the chat application, but it's up to whatever design you want. If you have no need for logs, just use normal sockets.
Related
I want to make an app which lets users comment and send messages. However, the notifications for these events will have to come instantly, just like any other social-media or chat application. This is what I'm thinking of:
Web-frontend: Angular, mobile: Ioinc with Angular
Backend: Node, Mongo
Now, this is how I was thinking I'd implement real-time notification.
There's a constant socket connection between the frontend (web & mobile-app) and the backend.
Whenever a message arrives, targeted to a specific user, I'll use some kind of a Mongo-hook to send the notification to the frontend via the socket connection.
Now, the confusion with this approach is:
Would millions of socket connections work at scale, at all? If not, what is the way to implement this pub-sub kind of system? I need to do it from scratch, not using Firebase.
What if a user is offline when he receives the message in the backend? If the socket is not on, how would he get the message? Is there a way to do it using Kafka? Please explain if you have some ideas on this.
Is this the correct approach? If not, can you suggest what would be appropriate?
Would millions of socket connections work at scale, at all? If not, what is the way to implement this pub-sub kind of system? I need to do it from scratch, not using Firebase.
Yes, it can work at scale just you have to made an architecture like that. You might find this useful
Scalable architecture for socket.io
https://socket.io/docs/v3/using-multiple-nodes/
What if a user is offline when he receives the message in the backend? If the socket is not on, how would he get the message?
If he the socket is not on or user is offline, then client Socket will be disconnected. At this point, notification will not be received and whenever the user comes online you'll have make an API call to get the notifications and connect again to the socket for further operations.
Is there a way to do it using Kafka?
Yes, you can also do it with Kafka. You'll need Consumer API(Subscriber) and Producer API(Publisher)
https://kafka.apache.org/documentation/#api
https://www.npmjs.com/package/kafka-node
Sending Apache Kafka data on web page
What do you use Apache Kafka for?
Real time notification with Kafka and NodeJS
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
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.
Do I need to use a websocket to send JSON data to my client? (it's a tiny session description)
Currently my client-side code sends a session description via XHR to my Node.js server. After receipt, my node server needs to send this down to the other client in the 'room'.
I can achieve this using socket.io, but is it possible to do anything a bit faster/ more secure, like XHR for example?
If you just want to receive the offer from the other side and nothing else, I would suggest you to try HTML5 Server Sent Events.
But this may bring problems due to different browsers support, so I would use a simple long pooling request. Since you only want to get the SDP offer, the implementation is pretty simple.
No, you don't need to use the WebSocket API to send JSON data from client to client via a server, but unless you use Google's proprietary App Engine Channel APIs, then the WebSocket API is probably your best choice.
Also, please keep in mind that you're not only sending session descriptions, but also candidate info (multiple times) as well as other arbitrary data that you might need to start/close sessions, etc.
As far as I know, the WebSocket API is the fastest solution (faster than XHR) for signalling because all the overhead involved with multiple HTTP requests is non-existent after the initial handshake.
If you want to code things yourself, I'd start reading the latest WebSocket draft and learning how to code the WebSocket server-side script yourself or else you will pretty much have to rely on a WebSocket library like Socket.IO or a proprietary solution like Google's App Engine Channel APIs.
How about using the 303 HTTP status code?
The first client send the session description to resource X, the server acknowledges the receipt and responds with a 303 status code that points to a newly created resource Y that accumulates other clients session descriptions.
The first client polls resource X until it changes.
The second client send its session description to resource A, the server acknowledges the receipt and updates resource Y. The first client notices the update with the next poll and will now have the second client's session information.
I'd like to implement push notification server using node.js. The basic scenario is:
Some applications sends notification messages to the server.
Notification server receives the request and forwards the message to uesr's mail or IM client based on user's preference.
In step 1, which protocol (e.g. REST, socket, HTTP/XML and so on.) would you recommend from the performance perspective?
Also in step 2, I have a plan to use node-xmpp module for IM client but for mail, which way is the best to implement? For example,
Just use SMTP. (But I think this might occur performance degradation because SMTP is an expensive communication and performance depends on SMTP server capacity.
use queue mechanism, in order to avoid drawbacks from the above. node.js app simply puts the message into the queue, and smtp server pulls the message.
other solutions...
Thanks in advance.
With regards to what to use as a protocol, i would go for a REST interface, whereby the application posting sends a POST request to a resource associated with the USER. something along the lines of "http://example.com/rest/v1/{userID}/notifications
I personally would use json as the data/content of the rest request and have node.js write this information to a message queue. (as a json string).
You can than have xmpp readers for each user, as well as an SMTP handler reading from this queue as fast as the SMTP server allows it to go.
However, this full post is what i would do in your situation, rather than a factual response on what is best. I know JMS fairly well and i've been working a lot with rest interfaces lately, therefore this is the way i would do it.