shamblett / mqtt_client

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

Need shorter timeout when connection can't be established #522

Closed Vera-Spoettl closed 4 months ago

Vera-Spoettl commented 8 months ago

I'm setting the connection timeout period to 1000 milliseconds. However the connect attempt takes more than a minute until it returns with an error. Is there a possibility to shorten this? In my case something like 10 seconds would be more appropriate.

flutter: 1-2024-03-16 15:36:44.909549 -- MqttClient::connect - Connection timeout period is 1000 milliseconds
flutter: 1-2024-03-16 15:36:44.910590 -- MqttClient::connect - keep alive is enabled with a value of 2000 seconds
flutter: 1-2024-03-16 15:36:44.910963 -- MqttConnectionKeepAlive:: Initialised with a keep alive value of 2000 seconds
flutter: 1-2024-03-16 15:36:44.911001 -- MqttConnectionKeepAlive:: Disconnect on no ping response is disabled
flutter: 1-2024-03-16 15:36:44.911501 -- MqttConnectionHandlerBase::connect - server 192.168.50.1, port 1883
flutter: 1-2024-03-16 15:36:44.912061 -- SynchronousMqttServerConnectionHandler::internalConnect entered
flutter: 1-2024-03-16 15:36:44.912135 -- SynchronousMqttServerConnectionHandler::internalConnect - initiating connection try 0, auto reconnect in progress false
flutter: 1-2024-03-16 15:36:44.912284 -- SynchronousMqttServerConnectionHandler::internalConnect - insecure TCP selected
flutter: 1-2024-03-16 15:36:44.912536 -- SynchronousMqttServerConnectionHandler::internalConnect - calling connect
flutter: 1-2024-03-16 15:36:44.912705 -- MqttNormalConnection::connect - entered
flutter: 1-2024-03-16 15:37:59.920919 -- MqttConnectionBase::_onError - calling disconnected callback

Thanks for your help!

shamblett commented 7 months ago

The connection timeout period from the API -

/// Connect timeout value in milliseconds, i.e the time period between
 /// successive connection attempts.

its the period between successive connection attempts(to allow backoff if needed) not the period the connection must complete in. There is no client setting for this. In your case the network layer seems to be holding the socket for 1min 15 seconds then erroring.

Do you ever successfully connect or does it do this every time? If its every time I'd look at your network layer.

Vera-Spoettl commented 7 months ago

Ok. Sorry for misunderstanding the parameter and thanks for pointing out the docu.

Maybe I explain my use case: I have an external device which is the mqtt server. When the user clicks a button in my app, it should try to connect to this external device. When the external device is not turned on, I give the user an error message and tell him to switch on this device.

Therefore, I try to connect via mqtt. When the device is working, everything is fine and the connection is established quite fast. When the device is not switched on, the time until I get an exception is just too long for my use case.

Any idea how I could solve this?

laterdayi commented 7 months ago

Yes, the problem I encountered should be the same as yours. If the mqtt server is not opened, it takes too long for me to receive the exception. Sometimes it takes a few minutes and sometimes it takes longer. Sometimes I don’t even receive the exception reminder. This way I have no way of knowing my current connection status and no way of manually disconnecting and reconnecting

shamblett commented 7 months ago

Have you tried not connecting the client to a device you seem to know is not switched on? This relatively pointless as it will never work. You can use many other methods(ping etc.) to determine if your device is switched on before trying to connect.

Vera-Spoettl commented 7 months ago

I have an app which will control the external device. I don't know if the user has turned on this device or not. Therefore, I try to connect via MQTT and use the result as an "turned on and connected" indicator. MQTT connection established => everything is fine. MQTT throws a timeout exception => ask the user to turn on the device before he tries again to connect.

laterdayi commented 7 months ago

https://github.com/shamblett/mqtt_client/issues/523

Are you saying the same thing about this need?

shamblett commented 7 months ago

@laterdayi Its hard to tell, do you know if your device is on or not before you try to connect?

@Vera-Spoettl The MQTT protocol is not useful for detecting whether devices have been switched on or not, your using the wrong tool especially in the context of Dart/flutter, see below.

The client sits atop the Dart/flutter runtime and reacts to events produced by the runtime, if the runtime produces no events or takes minutes to do this there is nothing the client can do. If you want an explanation as to why the runtime can take over a minute to detect an error in the network stack before it communicates this to the client then please ask the google Dart/flutter guys not me.

Why can't you just ping the device? This will at least tell you the device is alive, note it doesn't matter if the MQTT broker is running or not, the client can handle this on connection.

Vera-Spoettl commented 7 months ago

We have to refactor the handling of the external devices. Up to now, we have no "check-in" of devices when they are switched on. However this will be implemented in one of the next releases. Otherwise this solution won't be scalable. For release 1.0 we have only one external device and no more time to implement it properly. I wanted to solve it in the way described, but I think I have to implement a ping until we have implemented the "check-in" for the devices.

laterdayi commented 7 months ago

Have you tried not connecting the client to a device you seem to know is not switched on? This relatively pointless as it will never work. You can use many other methods(ping etc.) to determine if your device is switched on before trying to connect.

Expect to solve first https://github.com/shamblett/mqtt_client/issues/523, to solve the current problems, thank you