I have used socket io and apollo subscription before, now I am looking for an alternative solution. I need something similar to subscriptions-transport-ws that allows client browser to subscribe events or channels from the server.
Simple example.
Let's say on the server-side is some kind of pub/sub broker. Now user opens an article and the comment section is updated in real-time. So when a user opens an article, he starts listening for events from that channel. It should work like on Twitter to display every new like and comment.
Related
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).
I want to implement a notification system like facebook does for an Angular 7 app. I am currently using nodejs ad my backend and socket io for the socket connection.
I understand the principle of sockets, events, observables... however, I can't wrap my head around how should I create a socket for each user to receive notifications.
I thought about creating a channel called 'notifications' and then subscribe all logged in users to that channel. When a user does anything that triggers an event that requires the app to create a notification I will broadcast the notification to all users and only display it if logged in user is inside the receivers array of the new notification object.
HOWEVER I think this is a very bad approach as all users will be listening to this event and only a very small amount of them will display it. It seems like I am wasting a lot of resources with this approach. Is there a proper way to handle this or is my approach the one used by companies like Facebook and Instagram
I have a REST API server powered by express+mongodb. There are a couple of endpoints with different resources. One of them is chat API. I already have several basic endpoints like:
POST http://api.example.com/v1/chat - to create chat
POST http://api.example.com/v1/chat/:id/message - to send message to existing chat
GET http://api.example.com/v1/chat/:id/messages - to get messages in the the specified chat
But I need to provide a way for API consumers to efficiently get new messages in real-time without reloading the page.
For now as you see it's possible just to poll GET endpoint from client but it seems not performant. For example client can have UI which will show new messages count in header (some kind of notifications).
I was thinking about websockets. Is it possible for example to provide endpoint like /chat/:id/subscribe which will proxy sockets' server and connect to it on client?
Is there some good examples of such API design where I can get inspiration from or maybe you can give me piece of advice? Thanks!
socket.io is the package you are looking for.
The namespace section in it's documentation is a good solution because namespaces can be authorization protected. It represents a pool of connected sockets.
Here is how I would do it :
Create a document for the chat between the two users with this route :
POST http://api.example.com/v1/chat
Create a namespace with socket.io when a user sends a message to another connected user and store it into your user's document in your database. This route would create a namespace and/or emit the message :
POST http://api.example.com/v1/chat/:id/message
In the client, you have to use socket.io again to listen to the messages in the namespace.
UPDATE FOR SCALABILITY :
Here is a good stackoverflow answered question about implementing a scalable chat server : Strategy to implement a scalable chat server
As you can see in this post, mongodb might not be the best solution to store your messages.
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.
I am trying to build a generic publish/subscribe server with nodejs and node_redis that receives requests from a browser with a channel name and responds with any data that has been published too that channel. To do this, I am using long polling requests from the browser and dealing with these requests by sending a response when a message is received on a channel.
For each new request, an obect is created for subscribing to the channel (if and only if it does not already exist).
clients = {};
//when request comes in,
clients[channel] = redis.createClient();
clients[channel].subscribe(channel);
Is this the best way to deal with the subscribtion channels, or is there some other more intuitive way?
I don't know what's your design, but you can subscribe with one redis client on multiple channels (after you subscribe with client, then you can only subscribe to other channel or unsubscribe within this connection: http://redis.io/commands/subscribe), because after you receive message, you have full information which channel this message comes from. Then you can distribute this message to all interested clients.
This helped me a little, because I could put type of message in channel name and then dynamically choose action for each message from small function, instead of generating separate subscription for each channel with separate logic.
Inside my node.js server I have only 2 redis clients:
simple client for all standard actions - lpush, sadd and so on
subscribe client - which listens for messages over subscribed channels, then this messages are distribute to all sessions (stored as sets for each channel type) using first redis client.
I would like to point you out to my post about pubsub using socket.io together with redis. Socket.io is a very good library =>
How to use redis PUBLISH/SUBSCRIBE with nodejs to notify clients when data values change?
I think the design is very simple and it should also be very scalable.
That seems like a pretty reasonable solution to me. What don't you like about it?
Something to keep in mind is that you can have multiple subscriptions on each Redis connection. This might end up complicating your logic, which is the opposite of what you are asking for. However, at scale this might be necessary. Each Redis connection is relatively inexpensive, but it does require a file descriptor and some memory.
Complete Redis Pub/Sub Example (Real-time Chat using Hapi.js & Socket.io)
We were trying to understand Redis Publish/Subscribe ("Pub/Sub") and all the existing examples were either outdated, too simple or had no tests.
So we wrote a Complete Real-time Chat using Hapi.js + Socket.io + Redis Pub/Sub Example with End-to-End Tests!
https://github.com/dwyl/hapi-socketio-redis-chat-example
The Pub/Sub component is only a few lines of node.js code:
https://github.com/dwyl/hapi-socketio-redis-chat-example/blob/master/lib/chat.js#L33-L40
Rather than pasting it here (without any context) we encourage you to checkout/try the example.
We built it using Hapi.js but the chat.js file is de-coupled from Hapi and can easily be used with a basic node.js http server or express (etc.)