We're using RabbitMQ and its Web Stomp plugin for websockets for several projects at work.  Using a Stomp.js library in the browser, our app users connect and subscribe to topics using their username and JWT, which we validate using a custom HTTP back end auth in Rabbit.  I've recently written a rest-over-stomp module for ColdBox MVC which allows you to push the response of any Coldbox event or API call out over a websocket channel to any browser listening on that channel.  This allows for the following

  • Browser can request data and receive it async
  • Any random server-side process can simply decide to push fresh data out to browser
  • Each user subscribes to a custom topic specific to them (via permissions enforced by my custom HTTP backend auth) so I have a direct data bus to any users's browser
  • Unlike Ajax calls, there is no HTTP/TCP negotiation of each request since the websocket is a persistent connection to the server

Detect if a User is Online

The reason I wrote this post however was to show a nice trick to detect if a user is online.  For example, a back end process on the server decides that some data for a user is out of date and wants to push that data out to the user's browser so they have the latest copy.  However, if the user just closed their browser and is no longer online, I don't want to perform the work of collecting fresh data and publishing it to a RabbitMQ topic for which there are no STOMP subscribers.  Since I'm authenticating each user with their username and JWT from the browser, I can use the RabbitMQ management API to tell if any given user is online, or at least connected to my RabbitMQ server right then before I push out data over a topic for them.  You must have the RabbitMQ management plugin installed to use the API.

Here is a simple function that I use inside a CommandBox task runner to detect if a given user is online based on their unique username sent when their browser authenticates to Rabbit.

function isUserOnLineRightNow( required string name ) {
  if( local.result.status_code == 200 && isJSON( local.result.fileContent ) ) {
    return !!deserializeJSON( local.result.fileContent ).find( (c)=>c.user == name );	
  print.redLine( 'Unable to check RabbitMQ management API for online users. #local.result.statuscode# #local.result.errordetail# #left( toString( local.result.fileContent ), 100 )#' )
  return false;

You can hit that API endpoint directly in a browser and enter your Rabbit admin username and password in the basic auth prompt of your browser to see the data.