Managing Multiple MQTT Connections from Single Device

I’m working on a system that is deployed as a collection of composable microservices to various gateway machines. Depending on the deployment an end user can have a few different services needing an MQTT connection.

Typically I would just use a randomly assigned MQTT client ID but the restriction that I need to authenticate with a valid losant device ID is hanging me up. As far as I can tell the broker is pretty good about enforcing uniqueness of client sessions and the amount of reconnecting required could prove problematic, especially for long lived subscriptions. I could model an additional device for each service that needs to connect but I’m not sure how well that will scale in larger environments, and it doesn’t really match the way the system is deployed that well.

Wondering before I get too deep if there is an established practice I could follow for this kind of situation.

Thanks a lot

Alex

@Alex_Ullrich,

Great question!

I have a couple of recommendations that should help here.

First, have you considered reporting state using HTTP (Webhooks or the Rest API)? Using Webhooks, you can authenticate using basic auth. Using the Rest API, you can authenticate using API Tokens.

Since HTTP doesn’t have the same clientId restrictions, it would allow you to send data to Losant from all of your microservices effectively.

Secondly, you mentioned that these microservices live on Gateways. Are you using the Losant Edge Agent?

If you have any questions, don’t hesitate to ask, I can elaborate on these more if needed.

Thanks, we’ve considered reporting via HTTP but focused on MQTT because it seems less resource-intensive and gives us more options for disconnected scenarios.

This isn’t actually a problem for publishing, I just initialize the connection each time. But I have a command service that needs to listen to a topic for a long period, that is where it seems to fall down.
So what I am doing now is using the gateway’s ID from losant for any publisher (right now a state microservice and another that sends messages on local device definition changes) and a dummy ID for every subscriber. But this doesn’t scale all that well - I was wondering if maybe I could append some kind of hash to the device ID I use currently or something like that.

Regarding the edge agent, we have setups that use it but also others that publish straight from our services to the cloud.

Thanks again,

Alex

1 Like

@Alex_Ullrich,

Ah, I see. Overall, our broker does require a unique connection for each Device ID. I do know we have some tickets to allow for application-level broker access, which could solve your problem here. I can add this to that ticket and let you know if that gets released.

For now, here are some more things to consider:

Using the Edge Agent’s local broker would allow you to have all of your services talk to the Agent via local MQTT (instead of connecting to the cloud, thus requiring a unique connection per Device ID). In the Edge Agent, since it’s a local broker, you have more control as to how it’s configured.

Initialize the connection each time to publish makes sense. However, to subscribe to device commands:

  • A device would have to listen to its command topic. But, as you know, you can’t use that device’s connection for multiple devices.
  • You can poll the Rest API to receive the last Device Command. This is used when you want to listen for commands, but not have to maintain a persistent connection using MQTT.

With that being said, if you want each local service to listen to commands and maintain it’s own connection, each would have to be a device within Losant.

Just as a thought: Would it be possible for one service to “listen” and forward the messages to the right place locally?

In certain environments it is possible for sure. We are mainly using a zeroMQ bus to chain the services though (through EdgeXFoundry) and some of the limitations inherent to the brokerless model can make it tricky.

Appreciate you laying out the other options I will look into those for sure. Application level access to the broker (or some kind of hash appending scheme like losant-device-id#publisher) does sound like it would likely eliminate the problem all together.

Thanks again,

Alex

@Alex_Ullrich,

No problem. I’ll be sure to follow up on that feature.

If you have any other questions as you’re building don’t hesitate to ask!

Will do thanks again. We only have three ‘channels’ right now - device state through one service, device definition updates through another (this is a good candidate for HTTP I think since they should be pretty infrequent) and southbound commands through a third.

I think something that might scale pretty well for this is to register the gateway as a system - then we can register each service that needs a connection underneath that system as a gateway. Using tags these could be consistently treated as ‘gateway services’ under the system within workflows.

1 Like