1
votes

I'm trying to subscribe to multiple topics using HiveMQ client. This page suggests that the MQTT subscribe message can carry multiple subscriptions.

I tried this code but it only subscribes to the last topic (Topic2 in this example)

val mqttClient: Mqtt3AsyncClient

// Client instantiation ommited for brevity

mqttClient.subscribeWith()
    .topicFilter("Topic1")
    .topicFilter("Topic2")
    .callback(::onMessageReceived)
    .send()

If possible, I would like to avoid having to send multiple separate subscriptions.

1
Is your topic structure suitable for a wildcard filter?hardillb
@hardillb No, it is not suitable for a wildcard filter. In order to minimize load on the client, I only want to subscribe to a subset of the topics.Jordi
Then maybe redesign your topic structure so you can make use of either # or + to filter topics, otherwise you have no choice but to subscribe to each topic you want individually.hardillb

1 Answers

3
votes

You are correct in that the MQTT subscribe payload contains "a list of Topic Filters indicating the Topics to which the Client wants to subscribe". So you can, in theory, subscribe to multiple topics with a single call.

Subscribing to multiple topics with one call can make error handling difficult (if one subscription succeeds and another fails is that an error?) so some libraries may not support this and others offer a simplified syntax for single topic subscriptions. In the hive-mqtt-client (which I'm assuming you are using) a call to topicFilter() overrides any existing filter so you will get a subscription to the last topic specified.

Subscribing to multiple topics within one call has been discussed in the forum and it appears that there are a number of ways of achieving this (see this issue and this PR). Example code from the forum follows (I have not tested this):

mqtt3AsyncClient.subscribeWith()
.addSubscription().topicFilter(“tenant1/topic”).qos(MqttQos.AT_LEAST_ONCE).applySubscription()
.addSubscription().topicFilter(“tenant2/topic”).qos(MqttQos.AT_LEAST_ONCE).applySubscription()
.callback(e -> {})
.send();