Sending Message to a specific session on Spring Websocket
Recently I worked on a project where requirement was to show the progress on long running job in front end application. One of the approach to achieve this is poll the database at regular interval using service. But this approach has some drawbacks, imagine you have thousands of application users and every user is waiting for updates. If application is polling the status information from database at regular interval then there are 1000 users making that request at regular interval adding load on database, this is not scalable at all. Hence i decided to do this using push notifications. Push notifications means server will push the information to client, in this specific case if there are any updates about the long running job server will push that update to client.
Websocket can be used to send push notification. A proper introduction to websocket protocol is beyond the scope of this post. At minimum it is important to understand that websocket allows full duplex, two way communication between client and server.
Now that i decided to use websocket to send push notification to application. I decided to write Websocket service using Springboot because my backend is Java and I wrote client/front end application in Angular. At high level Springboot service exposes a websocket endpoint and angular application subscribes to websocket endpoint. With this all updates will be sent to all instances of application, however instead of broadcasting updates to all clients i wanted to broadcast it to specific user/client. And this is where things started to get complicated. I did some research online and most of springboot samples i found were able to send updates to specific user but they all were using spring security. I wanted to do it without spring security (because security is handled by API gateway in my case). I also found few references suggesting that it is possible to send updates to specific session but none of the samples worked for me. So in this post i will explain how i achieved sending updates to specific session.
Step 1: Angular Application Subscribes to Websocket & Registers itself
I used sockjs & stompjs in Angular. Angular application will subscribe to websocket channel. Sample code provided below
Once connected application should register itself by passing session id and transaction id. Here i am generating transaction id for demo purpose but in real world it can be a jobid of long running process.
When application is closed un-register application
Step 2: Springboot
Configure Websocket
Define controller
I already had a messaging setup with RabbitMQ. So I modified long running process to push the updates to rabbitmq queue rather than using database trigger. RabbitMQ receiver code is provided below
Once the message is received with jobid and status, springboot service will reverse lookup session id from jobid and will push updates to specific session.
Here is the GitHub link to the sample project https://github.com/RahulMetangale/message-to-specific-session
I hope you find this useful. If you do find this useful please clap for me.Thanks!