Real-Time Data Delivery on Spring Boot Using ActiveMQ and STOMP over WebSockets - Part 2
In the previous article we made a very simple app that sent updates to clients in real-time, and in this article, we’ll build on that example and make a slightly more complicated app; a private messaging app.
In the first example messages were broadcast to all client, but this time we’ll authenticate users with
Spring Security and target them specifically by using STOMP’s user-specific methods. We’ll also use a message queue (namely,
Apache ActiveMQ, which must be installed on your computer) to temporarily store messages before sending them out. And as for the transport between the queue and our message dispatchers, we’ll use
For a downloadable version of this code visit the Github repository at https://github.com/ygunayer/realtime-messaging
So, let’s begin by adding the new dependencies to our build script:
And then, configuration. For simplicity’s sake we’ll configure an in-memory authentication with three built-in users. The users are as follows:
And here’s the configuration.
Next, we’ll tell Apache Camel to listen for changes on a certain queue, and when a new message is inserted, redirect it to our own message dispatcher beans (the Camel route will be as follows:
apache:activemq -> bean:queueHandler). One thing to note, however, is that Camel will try to create and use an in-memory ActiveMQ instance. Since we don’t want that, we’ll have to tell it to use our own ActiveMQ instance, which by default runs on
If you’ve just installed ActiveMQ or haven’t changed much of its settings, you can visit http://localhost:8161 and follow the “Manage Broker” link to monitor the status of your queues. When prompted for credentials, use
adminfor both username and password.
Okay! Now let’s look at our WebSocketController class which has changed slightly. This time it’ll notify all clients when a user joins the topic.
Then, let’s modify our MessageDTO class slightly by adding two new fields;
to, and move it to its own file so it can be discovered by ActiveMQ while serializing/deserializing.
Then, the controller. We only need two functions: receive “send message” requests from clients and send them to ActiveMQ, and provide a list of users who are logged-in. To send messages to ActiveMQ we’ll use the Camel context instance and to retrieve the list of users we’ll use Spring Security’s session registry.
Then, the message dispatcher. This is just a named Spring component which will be realized by Camel when a message is added to the queue. The only function of this class is to send a message to its recipient, but if we somehow wanted to process our message in some kind of way (say, sending mails), we could do it here.
And finally, the client code. This time it’s a little bit more complicated, but still no biggie.
And here’s a demonstration:
That’s it! Well… almost. With authentication, message persistence and user-specific message dispatching as well as broadcasting, this example has been more realistic, but as always, there’s still more to do. While we’ve persisted messages, there’s still a chance that they might get lost because unless specified otherwise, they won’t be added back to the queue if an error occurs while they’re being processed. The solution is to use a
Hopefully in the future I’ll create a better, more in-depth articles to illustrate points that need special care, but until then, stay tuned.