paho.mqtt.c icon indicating copy to clipboard operation
paho.mqtt.c copied to clipboard

When no set MQTTVersion,Connection timeout not work, application hangs

Open zhenjing opened this issue 3 years ago • 4 comments

Version 1.3.9 sample code: MQTTClient_publish.c Problam same with https://github.com/eclipse/paho.mqtt.c/issues/358

While debugging I found this working configuration:

  1. MQTTClient_connectURI(...) started
  2. start variable set to current timestamp
  3. first call to MQTTClient_connectURIVersion(...)
  4. second call to MQTTClient_connectURIVersion(...) due to 3) error Within the MQTTClient_connectURIVersion there is a time elapsed calculation (MQTTClient_elapsed function calls). MQTTClient_waitfor(...) with timeout parameter set to millisecsTimeout - MQTTClient_elapsed(start) calls Thread_wait_sem(sem, timeout) that calls WaitForSingleObject(sem, timeout).

MQTTClient_connectURI function, MQTTClient.c line 1643: if (MQTTVersion == MQTTVERSION_DEFAULT) { rc = MQTTClient_connectURIVersion(handle, options, serverURI, 4, start, millisecsTimeout, connectProperties, willProperties); if (rc.reasonCode != MQTTCLIENT_SUCCESS) { rc = MQTTClient_connectURIVersion(handle, options, serverURI, 3, start, millisecsTimeout, connectProperties, willProperties); } }

If MQTTVersion == MQTTVERSION_DEFAULT, first MQTTClient_connectURIVersion will timeout, and second call MQTTClient_connectURIVersion, MQTTClient_waitfor Timeout < 0, MQTTClient_cycle API causes an almost infinite waiting effect.

Trace log: Trace : 3, 20220812 113021.364 MQTTClient_waitfor millisecsTimeout 3000 MQTTTime_elapsed 3078 Trace : 3, 20220812 113021.364 MQTTClient_waitfor Timeout -78 Trace : 3, 20220812 113021.364 (34428) (3)> MQTTClient_waitfor:2590 Trace : 3, 20220812 113021.365 (34428) (4)> MQTTClient_cycle:2489 Trace : 3, 20220812 113021.365 (34428) (5)> Socket_getReadySocket:252 Trace : 3, 20220812 113021.365 (34428) (6)> Socket_continueWrites:995 Trace : 3, 20220812 113021.365 (34428) (6)< Socket_continueWrites:1025 (0) Trace : 3, 20220812 113021.365 (34428) (5)< Socket_getReadySocket:328 (0) Trace : 3, 20220812 113021.365 (34428) (5)> MQTTClient_retry:2469 Trace : 3, 20220812 113021.365 (34428) (6)> MQTTProtocol_retry:804 Trace : 3, 20220812 113021.365 (34428) (6)< MQTTProtocol_retry:823 Trace : 3, 20220812 113021.365 (34428) (5)< MQTTClient_retry:2479 Trace : 3, 20220812 113021.365 (34428) (4)< MQTTClient_cycle:2577 (0) Trace : 3, 20220812 113021.365 (34428) (4)> MQTTClient_cycle:2489 Trace : 3, 20220812 113021.365 (34428) (5)> Socket_getReadySocket:252 Trace : 3, 20220812 113021.365 (34428) (6)> Socket_continueWrites:995 Trace : 3, 20220812 113021.365 (34428) (6)< Socket_continueWrites:1025 (0) Trace : 3, 20220812 113021.365 (34428) (5)< Socket_getReadySocket:328 (0) Trace : 3, 20220812 113021.365 (34428) (5)> MQTTClient_retry:2469 Trace : 3, 20220812 113021.365 (34428) (6)> MQTTProtocol_retry:804 Trace : 3, 20220812 113021.365 (34428) (6)< MQTTProtocol_retry:823 Trace : 3, 20220812 113021.365 (34428) (5)< MQTTClient_retry:2479 Trace : 3, 20220812 113021.365 (34428) (4)< MQTTClient_cycle:2577 (0) Trace : 3, 20220812 113021.597 (34428) (4)> MQTTClient_cycle:2489 Trace : 3, 20220812 113021.597 (34428) (5)> Socket_getReadySocket:252 ...........

zhenjing avatar Aug 12 '22 03:08 zhenjing

If set MQTTVersion, then MQTTClient_connectURI API will be called one time, and Connection timeout work!

zhenjing avatar Aug 12 '22 03:08 zhenjing

MQTTVERSION_DEFAULT tries to connect with MQTT version 3.1.1 first. If that fails it drops back to MQTT version 3.1, You would have to have an old broker to not support 3.1.1 these days.

if set MQTTVersion, then MQTTClient_connectURI API will be called one time, and Connection timeout work Set MQTTVersion to what?

MQTTClient_publish.c is a very simple example. It's not meant to work comprehensively. See paho_cs_pub.c for that.

icraggs avatar Aug 15 '22 15:08 icraggs

I use MQTTClient_connectURI API to check serverURI is valid. When the serverURI is invalid, such as 10.0.0.10:1883 (host invalid)、localhsot:18803 (port invalid) and so on, if no set MQTTVersion,connection timeout not work, application hangs.

zhenjing avatar Aug 16 '22 02:08 zhenjing

MQTTClient_connectURI doesn't valid the serverURI. And port 18803 is a valid port. Valid ports are from 1 - 65535. The broker can run on any port.

jumoog avatar Aug 16 '22 09:08 jumoog

So it's better to set the MQTTVersion in this case, to not MQTTVERSION_DEFAULT, which tries both MQTT 3.1.1 and 3.1 in sequence. You're depending on DNS timeouts, or an error response or lack of response from the server, varying on the case. The reply could come back quickly or not, depending on the different situations.

I'm thinking of changing the default behaviour to MQTT 3.1.1 only in version 1.4.0 of the library, as I don't think there are many brokers which only support 3.1 any more.

icraggs avatar Sep 30 '22 12:09 icraggs