edgexfoundry / edgex-examples

Apache License 2.0
51 stars 52 forks source link

How to (re)use the single MQTT connection in a custom app service for subscribe and publish topics? #241

Closed jiekechoo closed 4 months ago

jiekechoo commented 5 months ago

I followed the example service cloud-export-mqtt code, a custom app-service to connect my cloud was worked, but I need the same MQTT connection to subscribe a few topics. How to do it?

Thanks.

lenny-goodell commented 5 months ago

@jiekechoo , to subscribe to topics from the cloud broker you must use the MQTT Trigger. It will not share the MQTT connection use to export to the Cloud. You will need to use unique ClientID for each connection.

Example MQTT trigger configuration can be found here: https://github.com/edgexfoundry/app-service-configurable/blob/main/res/external-mqtt-trigger/configuration.yaml#L49-L69

Note that the SubscribeTopics: is a comma separated list of topics.

jiekechoo commented 5 months ago

@lenny-intel ,thanks for your help.

I tried to develop a new app-service for the enterprise/cloud, not using two services. The cloud only allows one connection with the mqtt client, so i need to make a new app-service using one mqtt connection.

jiekechoo commented 5 months ago

I would like to try, add a feature about this issue, maybe someone needs it.

lenny-goodell commented 5 months ago

The MQTT broker will allow multiple connections if the client IDs for each connection are unique. Please try this.

lenny-goodell commented 5 months ago

Actually, I don't think the external trigger is what you want here since you need the event data flowing from the EdgeX MessageBus to the MQTT Export pipeline. Since this is a custom App Service you can create your own MQTT Export where to the client (already connected) is passed into the constructor for the your MQTT Export pipeline function. Then you also have the client available to subscribe to topics and take actions based on data received from the cloud.

jiekechoo commented 5 months ago

The MQTT broker will allow multiple connections if the client IDs for each connection are unique. Please try this.

Some cloud platform does not verify the client ID, every device has its unique token and all communications must be in one MQTT connection to make sure the device status(such as: up/down, online/offline), it's very common.

jiekechoo commented 5 months ago

Actually, I don't think the external trigger is what you want here since you need the event data flowing from the EdgeX MessageBus to the MQTT Export pipeline. Since this is a custom App Service you can create your own MQTT Export where to the client (already connected) is passed into the constructor for the your MQTT Export pipeline function. Then you also have the client available to subscribe to topics and take actions based on data received from the cloud.

@lenny-intel Yes, it's right. If I use the external-mqtt-trigger and the custom App Service in two separate containers, it can't share the MQTT connection. It seems I have to modify the MQTTSecretConfig struct. Do you have any other advise?

lenny-goodell commented 5 months ago

You can simply add a GetClient() to return the client from the MQTTSecretSender. Call it after calling ConnectToBroker().

jiekechoo commented 5 months ago

You can simply add a GetClient() to return the client from the MQTTSecretSender. Call it after calling ConnectToBroker().

Thanks a lot. I'll try.

jiekechoo commented 5 months ago

@lenny-intel I have followed your advise, adding two functions: SetClient(opts MQTT.ClientOptions) and GetClient()(unsed) in the MQTTSecretSender, before calling ConnectToBroker() some opts added to the MQTT client, the Subscribe in single MQTT connection works good. May I create a pr for this feature?

lenny-goodell commented 5 months ago

Please rename SetClient to SetClientOpts. Yes, please create the PR.

jiekechoo commented 4 months ago

solved.