I have an application using Spring Framework / Spring Boot / Spring Messaging/Websockets and am going to be deploying it to Elastic Beanstalk. You can think of the application as a chat application (it actually does have chat features)
Scenario
Here is an example scenario:
Client A <-> Server A
Client B <-> Server B
Client C <-> Server B
Now, if Client A posts a message, using spring messaging, if I send that message to all connected clients, only Client A will see it because only Client A is connected to Server A, and likewise if Client B does, only Clients B and C will see it, not Client A.
So this leaves me with a problem of what options I have.
Possible Solutions
If possible, I would like to use an Amazon service as I am already in their cloud platform.
I thought about using Amazon SQS, having each server subscribe to the same queue, and then sending all notifications through it, but I believe all requests with SQS are active, so I would have to do polling, and would create a significant delay.
Does anyone know of a good solution for this problem? I can set up a server to handle all web-sockets, but that is not optimal.
Thanks in advance!
I am successfully doing almost exactly what you're describing.
Though I am not using spring boot, I am using spring and web sockets to send push message to browser clients when running in a cluster via elastic beanstalk.
The way I dealt with the cluster is by building a sub system where by I can send messages to other nodes.
So when I want to send a web socket message from node A I send the web socket message from that node (it will send to all it's registered clients) and then send a message to the other nodes for them to send to all their clients.
The "intra cluster" messaging is done with SNS + SQS. On startup each node creates a queue (identified by it's instanceid), registers that queue on a topic (all nodes use the same topic) and then starts a listener for new messages on that queue. This listener uses long polling. Amazon added support for "long polling" on it's queues a while back, it wasn't available at first. What it implies is that clients can block for up to 20 seconds waiting for a message, as soon as a message is received, that message will be processed - so your latency is very low. When I want to send a message a post to the topic and the message gets routed to all the queues registered on that topic. I also then built filtering in the listener to allow a message to go only to "other" clients (i.e. don't send this to myself option).
I see you did mention RabbitMQ... The weakness of my approach is that it does not support the richness that is possible if you use a message broker that supports the STOMP message protocol. Doing this means you don't have to worry about clustering at all, you just send to the broker and it handles the heavy lifting. I guess for me that would be my next step if I ever need a richer solution.
If someone could build a STOMP client backed by SQS that would be a boon for doing web socket message on spring in AWS.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With