shamblett / mqtt_client

A server and browser based MQTT client for dart
Other
552 stars 179 forks source link

Unsubscribe when the page exits, but updates. Listen is not destroyed #319

Closed jahnli closed 3 years ago

jahnli commented 3 years ago
MqttUtil.getInstance().mqttClient?.subscribe(_settingResponseTopic, MqttQos.atMostOnce);
final _clientTopicFilter = MqttClientTopicFilter(_settingResponseTopic, MqttUtil.getInstance().mqttClient!.updates);
_clientTopicFilter.updates.listen((List<MqttReceivedMessage> res) {
  final message = res[0].payload as MqttPublishMessage;
  final payload = utf8.decode(message.payload.message);
  if (json.decode(payload)['cal_setting_ok'] == 0) {
    Utils.showToast('changeError'.tr);
  }
  print(payload);

Unsubscribe when the page exits, but updates. Listen is not destroyed ,Multiple duplicate messages will be received if multiple exits are caused

shamblett commented 3 years ago

I'm not a flutter user so I don't really know what you mean by 'page exits' and 'multiple exits', updates.listen is only destroyed when the client is destroyed, it has to stay alive while the client is connected, regardless of what pages you are on. You maybe better asking flutter users.

jahnli commented 3 years ago

If multiple pages have multiple topics, updates. Listen needs to be written several times

jahnli commented 3 years ago

Do you need to write one (updates. listen) after each subscription topic, or write a global (updates. listen) and then modify it separately for each topic

shamblett commented 3 years ago

There is only one updates.listen, every subscribed topic will appear on it, if you want to filter these use topic filtering, see the mqtt_client_wildcard_filtered.dart example.

jahnli commented 3 years ago

The current situation is that I subscribed to one topic on page A and wrote an MqttClientTopicFilter updates. Listen. When I destroyed page A, I cancelled the subscription and re-subscribed to the topic when I entered page A again ,This resulted in repeated messages being returned multiple times in update.listen

jahnli commented 3 years ago

In the current situation, I wrote multiple updates. Listen, and the page was destroyed without destroying updates. Listen, resulting in duplicate messages

shamblett commented 3 years ago

Why are you unsubscribing and resubscribing again? This just causes unnecessary overhead, you are only changing pages, not going into background or exiting the app. Again you are better asking flutter users about this.

jahnli commented 3 years ago

OK, I see. Thank you for your advice

jahnli commented 3 years ago

I have a question, What's the difference between using res[0]. Topic in updaten.listen and MqttClientTopicFilter

shamblett commented 3 years ago

Topic filtering allows you to listen for multiple topics, you can attach a topic filter to client.updates, listen on it for your topic, then attach another filter to client.updates for another topic and so on. If you are only interested in a single topic there's no difference.

jahnli commented 3 years ago

client.updates!.listen((List<MqttReceivedMessage<MqttMessage?>>? c) { final topic= c![0].topic if(topic == 'topicA'){ }else if(topic == 'topicB){ }

Is this also possible if there are multiple topics? Is it different from MqttClientTopicFilter?

shamblett commented 3 years ago

Not in essence, you can do it that way if you wish, its up to you.

jahnli commented 3 years ago

Ok, thank you for your advice

jahnli commented 3 years ago

final _topicAFilter = MqttClientTopicFilter("topicA", MqttUtil.getInstance().mqttClient!.updates); _topicAFilter .updates.listen((List res) { final message = res[0].payload as MqttPublishMessage; final payload = utf8.decode(message.payload.message); });

final _topicBFilter = MqttClientTopicFilter("topicB", MqttUtil.getInstance().mqttClient!.updates); _topicBFilter .updates.listen((List res) { final message = res[0].payload as MqttPublishMessage; final payload = utf8.decode(message.payload.message); });

If using multiple MQTTClienttopicFilters, is it possible to write it this way? but It looks a bit too much code. Is there an easier way to write it

shamblett commented 3 years ago

No, that looks OK.

JacoFourie commented 3 years ago

You should subscribe to all the toppics on a onconnect event. Then Use Provider with MQTT and as the data arrives on a topic pass it to a method that updates the data inside provider. Place your Provider state at the top of the app and then you have access in all the pages and widgets to the data that comes in on a topic via Provider.