Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MQTT: subscribed several topics with retain flag but only the first topic is received #2039

Closed
boerge42 opened this issue Jul 12, 2017 · 8 comments

Comments

@boerge42
Copy link

boerge42 commented Jul 12, 2017

In my Lua-Code, i subscribe to several topics with retain flag ("myweather/lua_list", "weatherforecast/lua_list"):

m:on("message", function(client, topic, data) fill_lists(topic, data) end)

m:connect(mqtt_broker, mqtt_port, 0, 0,
		function(conn) 
			print("connected!")
			m:subscribe("myweather/lua_list", 0)
			m:subscribe("weatherforecast/lua_list", 0)
		end,
		function(conn, reason)
			print("MQTT-Connect failed: "..reason)
		end
)	

After the connect to the broker, only to the first topic ("myweather/lua_list") is called the callback-function fill_lists(). Only after publishing on the second topic ("weatherforecast/lua_list") is also received there something.

With the exchange of the two code lines (m:subscribe(...), the behavior turns around ("weatherforecast/lua_list" immediately, "myweather/lua_list" after renewed publication)

Hardware: ESP8266

NodeMCU-Version: 2.0.0 (built on: 2017-03-21 15:19)

@devsaurus
Copy link
Member

Does it help anything when you execute the second subscribe within the callback function of the first one?

Like in

m:subscribe("topic1“, 0, function (c)
  c:subscribe("topic2“, 0, function ()
    print("subscribe done")
  end)
end)

@boerge42
Copy link
Author

I just tried it...:

m:connect(mqtt_broker, mqtt_port, 0, 0,
    function(conn) 
        print("connected!")
        m:subscribe("sensors/+/lua_list", 0, function(c) c:subscribe("sensors/+/status", 0) end)                                                                
    end,
    function(conn, reason)
        print("MQTT-Connect failed: "..reason)
    end
)

The behavior is then completely unexpected and very wrong!
First, "topic1" is received --> OK
After a few seconds, "topic2" will also be received, but 4 times...! Thereafter only "topic2", although over this topic nothing more is sent.
Messages on "topic1" are no longer at all, even though they are sent to the broker...

connected!
sensors/esp8266-9982412/lua_list --> {heap="32448",temperature="25.7",humidity="61.8",unixtime="1499874267",readable_ts="2017/07/12 17:44:27"}
sensors/esp8266-10441060/lua_list --> {heap="32360",temperature="25.2",humidity="42.7",unixtime="1499874260",readable_ts="2017/07/12 17:44:20"}
sensors/esp8266-9982412/status --> on
sensors/esp8266-10441060/status --> on
sensors/esp8266-8671893/status --> off
sensors/esp8266-9982412/status --> on
sensors/esp8266-10441060/status --> on
sensors/esp8266-8671893/status --> off
sensors/esp8266-9982412/status --> on
sensors/esp8266-10441060/status --> on
sensors/esp8266-8671893/status --> off
sensors/esp8266-9982412/status --> on
sensors/esp8266-10441060/status --> on
sensors/esp8266-8671893/status --> off
sensors/esp8266-9982412/status --> on
sensors/esp8266-10441060/status --> on
sensors/esp8266-8671893/status --> off
sensors/esp8266-9982412/status --> on
sensors/esp8266-10441060/status --> on
sensors/esp8266-8671893/status --> off
sensors/esp8266-9982412/status --> on
sensors/esp8266-10441060/status --> on
sensors/esp8266-8671893/status --> off
...

Very crazzy, but unfortunately no solution...:-(

@FrankX0
Copy link
Contributor

FrankX0 commented Jul 13, 2017

When subscribing to multiple topics, why not using the example from the NodeMCU documentation:
http://nodemcu.readthedocs.io/en/dev/en/modules/mqtt/#mqttclientsubscribe
Works for me.

@boerge42
Copy link
Author

boerge42 commented Jul 14, 2017

That sounds good, I have not thought about it! I have tried this:

m:on("message", function(client, topic, data) 	fill_lists(topic, data) end)

m:connect(mqtt_broker, mqtt_port, 0, 0,
		-- Verbindung mit MQTT-Broker hergestellt
		function(conn) 
			print("connected!")
			m:subscribe(
						{
							["sensors/+/lua_list"]=0, 
							["sensors/+/status"]=0
						}, function(c) print("subscribed!") end)
		end,
		function(conn, reason)
			print("MQTT-Connect failed: "..reason)
		end
)	

It works, as expected / hoped ;-)! The latency is slightly larger than with one topic, but I get regulated in my programs ...

In any case, you should list this behavior / particularity perhaps in the documentation, right? The next one does not understand the world either...;-)

Thanks!

@marcelstoer
Copy link
Member

you should list this behavior / particularity perhaps in the documentation, right?

I don't understand this. As Frank pointed out it already is described in the documentation. What is it that you'd like to see added/modified? Feel free to submit a PR to this end.

@boerge42
Copy link
Author

boerge42 commented Jul 16, 2017

What is it that you'd like to see added/modified?

I would perhaps point out that the multiple-method is, under circumstances, the better method, or something like that....

But times to the real problem... I have experimented again today. Also with the multible-method, topics with the retain flag are swallowed after the start of the connection. At the latest from the fourth subscribed topic is final. It seems to depend on the length of the last message in the topic and the number of wildcards (+ and / or #) in the topic string. A system is not necessarily recognizable. Very unpleasant, since the result is not necessarily predictable.

@nwf
Copy link
Member

nwf commented Jul 21, 2017

@marcelstoer What appears in the documentation is that the callbacks clobber each other, so that
m:subscribe("foo",0,fn1) m:subscribe("bar",0,fn2) will only fire a fn2 callback. Nowhere (AFAICT) does the documentation say that one should not fire two :subscribe messages without waiting for a callback to succeed, and I don't think that that is a reasonable requirement, especially if one isn't using the callback argument to :subscribe. Am I missing something?

@nwf
Copy link
Member

nwf commented Jul 21, 2017

(Though perhaps this is indicative that we should change the API to have a :setSubscribeCallback method rather than taking the last, chronological, :subscribe as authoritative.)

marcelstoer added a commit that referenced this issue Aug 22, 2017
@marcelstoer marcelstoer added this to the 2.1 follow-up II milestone Aug 22, 2017
eiselekd pushed a commit to eiselekd/nodemcu-firmware that referenced this issue Jan 7, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants