Friday, April 06, 2018

Detecting ActiveMQ Connection Interrupts using the .Net Wrapper

While using ActiveMQ (via the ActiveMQ NMS client) in a C# codebase, I had a very difficult time trying to figure out how to properly detect a lost connection to the ActiveMQ service.  Things that seemed like they should've worked included:
  • ((Apache.NMS.ActiveMQ.Connection)connection).ITransport.IsConnected.  This returns true when completely disconnected.
  • ((Connection)connection).ConnectionInterruptedListener.  This never fires under normal configuration (details here).
I had to hook into the ConnectionExceptionListener like yay:

MessageBroker

IConnectionFactory factory = new ConnectionFactory(messageQueueConfigurationDef.BrokerUri);
IConnection connection = factory.CreateConnection(userName, password);
connection.ExceptionListener += ConnectionExceptionListener;

private void ConnectionExceptionListener(Exception ex)
{
  if (connection != null)
  {
    // Release this handler.
    connection.ExceptionListener -= ConnectionExceptionListener;
  }
  Invalidate();  // invalidating connection related objects here.
}

Subscriber
In my subscriber, I had to use this mechanism for detecting disconnection (and waiting for initial connection if necessary):
int period = 60000;  // or some configured value
heartBeatTimer = new Timer(unused_state =>
{
  if (!MessageBroker.IsConnected)  // returns false if Invalidate() above was called.
  {
     Subscribe;                    // Will trigger a re-connect above.
  }
}, null, 0, period);