Is it possible to create dynamic channels on Redis Pub/Sub? - websocket

I am going through how to scale the Web-socket based chat applications. As part of this I am exploring distributed Redis Pub/Sub to help send the messages to the Web-sockets servers the users are connected to.
Scenario: One to one chat
When User-A wants to chat with User-B. I want to create a chat room (channel) with name "room-User-A-User-B" and then let User-A and User-B to subscribe to this channel.
Question:
Is it possible to create channels and assign subscribers dynamically in Redis Pub/Sub?

Yes, you can subscribe to the dynamic channel using the SUBSCRIBE command. Also, you can create a group chat where you can subscribe to more persons dynamically using the SUBSCRIBE command.
But there's a catch if your publisher is also subscribed on the same channel then both will get data, so for messaging app you need to create two channels "room-User-A-User-B" and "room-User-B-User-A" B will subscribe on channel room-User-A-User-B and A will subscribe channel room-User-B-User-A.

Related

Is creating redis subscription for each connecting user a good approach to scale?

Context and Problem
We are building a notification system.
Publisher users can send messages to other online subscriber users
online subscriber users will receive the sent messages.
Publisher users and Subscriber users are on different instances and have no direct way to reach each other.
It's okay for subscribers to miss some notifications in rare scenarios (other methods of retrieving all notifications are provided)
Solution
- Publishing
Publisher user publishes a message into RabbitMQ.
Business logic is applied to the message in RabbitMQ consumer.
RabbitMQ consumer publishes the message to Redis event notification_[subscriber_id].
- Subscribing
Subscriber user connects to a WebSocket server.
WebSocket server has a connection to Redis and subscribes to Redis event notification_[subscriber_id] on user connection.
Upon receiving messages on notification_[subscriber_id] a message is sent to the user over WebSocket.
Question
Both publisher users and subscriber users can be any amount (infinite), from my research it seems Redis has no limit on the number of subscriptions (around 4billion if there's any), so
Is this "dynamic" way of creating subscriptions in Redis, scalable?
Yes,
you can scale horizontally in Redis Cluster mode, which will allow you to continue serving requests during the scaling process.
Also,
It will be smart to also design your application to cleanup subscriptions, as you seem to be planning to deal with millions/billions of subscriptions, so a good planning before implementation is important.

Is it possible to receive the same message on two clients?

We have one event producer and two clients (two different applications). These two clients have different roles but must receive the same events (order does not matter) from the same queue.
And I faced that a message will be consumed by only one client. Is it possible to receive the same message on two clients?
The most simple and effective solution to address this requirement is to use a bridge.
Basically you would bridge the queue used by the producer to another queue and you would have one client using the main queue and the other using the bridged queue.
For details you can check EMS documentation :
https://docs.tibco.com/pub/ems/8.6.0/doc/html/GUID-174DF38C-4FDA-445C-BF05-0C6E93B20189.html

Do I need to queue each message sent on Laravel or Pusher?

I'm trying to build a React Native chatting app using Pusher and Laravel as the backend. I want to know more about this environment, do I need to queue each message sent and receive by the user on my backend or just let Pusher do the job? Or it doesn't need a queue at all?? Which is the most suitable in this case?
You don't need to queue the messages, you can just send them and let Pusher broadcast them to the necessary subscribed clients. However, you should consider queuing or other solutions if you need sequential delivery or to retrieve messages that were not received correctly.
Check out their help page for a discussion on how to do this.

Why is the queue receiving the subscription event, but not my program?

Both the Solace queue and my program are subscribing to #LOG/INFO/SUB_ADD/DEVICE/ID/123.
When a new device which connects and subscribe to DEVICE/ID/123, both of them can successfully receive the subscribe event.
But, if I set subscription as #LOG/INFO/SUB_ADD/DEVICE/ID/>, only the solace queue receives the event.
Why can't my program receive the subscription event?
The problem persists even after my program sets it's subscription to #LOG/>.
One possible problem here is that there is an ACL rule preventing your application to subscribe to one or more topics in #LOG/INFO/SUB_ADD/DEVICE/ID/>. This can be easily verified with show log acl subscribe-topic.
If this is not the case, please revert back with the CLI outputs of show client <client-name> stats detail and show client <client-name> subscriptions to look further into the issue.

em-websocket with private channels

I need to create a web-socket server, I am planning to use em-websocket. I need to support private channels, that is I should be able to send message to one particular channel or subscriber.
There are many good chat examples that are in broadcast mode ie. they send the response to all the connected clients but I need to track each connected client somehow, and respond to each one separately. In other way, I need one private channel for each client so that I can respond to each client separately instead of broadcasting to all connected ones, make each web-socket connection unique
Can anyone guide me to right direction for implementing this or may be some example or gist.
Regards.

Resources