shamblett / mqtt5_client

A server and browser based MQTT 5 client for dart
Other
49 stars 25 forks source link

Question: How do i reduce the disconnect detection timeout? #51

Closed jonny7737 closed 1 year ago

jonny7737 commented 1 year ago

When testing my app for robustness i found that the MqttServerClient active connection times out at about 60 seconds. Can thhis time be reduced to 5 or 10 seconds?

shamblett commented 1 year ago

I'm not sure which timeout you are referring to, could you point me to the API call you are using here.

jonny7737 commented 1 year ago

With client.logging (on:true)

I get these logs:

flutter: 2023-02-26 10:02:30.419767 -- MqttConnectionHandlerBase::sendMessage - sending message started >>> -> MQTTMessage of type MqttMessageType.pingRequest MessageType = MqttMessageType.pingRequest Duplicate = false Retain = false Qos = atMostOnce Size = 0

flutter: 2023-02-26 10:02:30.420445 -- MqttConnectionHandlerBase::sendMessage - sending message ended >>> flutter: 2023-02-26 10:02:30.965216 -- MqttConnectionBase::_onError - calling disconnected callback flutter: 2023-02-26 10:02:30.966716 -- MqttConnectionBase::_onDone - calling disconnected callback flutter: 2023-02-26 10:02:30.967682 -- MqttConnectionHandlerBase::autoReconnect entered flutter: 2023-02-26 10:02:30.968456 -- MqttConnectionHandlerBase::autoReconnect - attempting reconnection flutter: 2023-02-26 10:02:30.968675 -- MqttConnectionHandlerBase::connect - server 10.211.55.7, port 1883 flutter: 2023-02-26 10:02:30.968732 -- MqttSynchronousServerConnectionHandler::internalConnect entered flutter: 2023-02-26 10:02:30.968787 -- MqttSynchronousServerConnectionHandler::internalConnect - initiating connection try 0, auto reconnect in progress true flutter: 2023-02-26 10:02:30.968842 -- MqttSynchronousServerConnectionHandler::internalConnect - calling connectAuto flutter: 2023-02-26 10:02:30.969189 -- MqttNormalConnection::connectAuto - entered flutter: 2023-02-26 10:02:30.971560 -- MqttConnectionHandlerBase::autoReconnect entered [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: SocketException: Operation timed out (OS Error: Operation timed out, errno = 60), address = 10.211.55.7, port = 49448

The unhandled socket exception is the the result of the timeout to which I am referring.

This log sequence appears approximately 60 seconds after I terminate the VM running the broker. The ERROR line does not appear in the logs again. I suspect that the ERROR log is the event that triggers the auto reconnect and is related to the last active connection to the broker.

Thank you for looking at this.

On Feb 26, 2023, at 3:28 AM, Steve Hamblett @.***> wrote:

I'm not sure which timeout you are referring to, could you point me to the API call you are using here.

— Reply to this email directly, view it on GitHub https://github.com/shamblett/mqtt5_client/issues/51#issuecomment-1445308069, or unsubscribe https://github.com/notifications/unsubscribe-auth/AK6S42TELJ7A2TOA723DFC3WZMO33ANCNFSM6AAAAAAVH5OFLM. You are receiving this because you authored the thread.

shamblett commented 1 year ago

OK thanks I see now.

The socket exception is raised from the hosts network layer through the Dart/flutter runtime, not by the package. looking at the socket API docs there doesn't seem to be a way for the package to affect this behaviour.

The autoreconnect seems to be being triggered when the send of the ping request fails, this is normal.

I see you are using keep alive pings, you could try dropping your keep alive time to say 3 seconds, when two responses are missed the client will disconnect itself, this should force close the socket.

jonny7737 commented 1 year ago

I have been using 5 second keep alive. Are you suggesting that the client should have disconnected after 10 seconds? If so then why does it take about 60 seconds to begin the auto reconnect loop?

On Feb 27, 2023, at 3:26 AM, Steve Hamblett @.***> wrote:

OK thanks I see now.

The socket exception is raised from the hosts network layer through the Dart/flutter runtime, not by the package. looking at the socket API docs https://api.dart.dev/stable/2.19.2/dart-io/Socket-class.html there doesn't seem to be a way for the package to affect this behaviour.

The autoreconnect seems to be being triggered when the send of the ping request fails, this is normal.

I see you are using keep alive pings, you could try dropping your keep alive time to say 3 seconds, when two responses are missed the client will disconnect itself, this should force close the socket.

— Reply to this email directly, view it on GitHub https://github.com/shamblett/mqtt5_client/issues/51#issuecomment-1445985603, or unsubscribe https://github.com/notifications/unsubscribe-auth/AK6S42VZ72PU36EYOB3PHITWZRXOHANCNFSM6AAAAAAVH5OFLM. You are receiving this because you authored the thread.

shamblett commented 1 year ago

Yes in normal operation keep alive failure should disconnect the client, when you kill the broker the client seems to become hung on the now defunct socket, the autoreconnect loop is starting -

flutter: 2023-02-26 10:02:30.420445 -- MqttConnectionHandlerBase::sendMessage - sending message ended >>>
flutter: 2023-02-26 10:02:30.965216 -- MqttConnectionBase::_onError - calling disconnected callback
flutter: 2023-02-26 10:02:30.966716 -- MqttConnectionBase::_onDone - calling disconnected callback
flutter: 2023-02-26 10:02:30.968456 -- MqttConnectionHandlerBase::autoReconnect - attempting reconnection
flutter: 2023-02-26 10:02:30.968675 -- MqttConnectionHandlerBase::connect - server 10.211.55.7, port 1883
flutter: 2023-02-26 10:02:30.968732 -- MqttSynchronousServerConnectionHandler::internalConnect entered
flutter: 2023-02-26 10:02:30.968787 -- MqttSynchronousServerConnectionHandler::internalConnect - initiating connection try 0, auto reconnect in progress true
flutter: 2023-02-26 10:02:30.968842 -- MqttSynchronousServerConnectionHandler::internalConnect - calling connectAuto
flutter: 2023-02-26 10:02:30.969189 -- MqttNormalConnection::connectAuto - entered
flutter: 2023-02-26 10:02:30.971560 -- MqttConnectionHandlerBase::autoReconnect entered

in the same second as the send fail is detected, I'm assuming the 60 seconds must be when it hangs on the socket as the first thing it tries to do is send a connect message although there is no timestamp on the exception.

jonny7737 commented 1 year ago

What I hear you saying is that there is nothing to be done about the 60 second delay, from the client perspective.

On Feb 27, 2023, at 7:02 AM, Steve Hamblett @.***> wrote:

Yes in normal operation keep alive failure should disconnect the client, when you kill the broker the client seems to become hung on the now defunct socket, the autoreconnect loop is starting -

flutter: 2023-02-26 10:02:30.420445 -- MqttConnectionHandlerBase::sendMessage - sending message ended >>> flutter: 2023-02-26 10:02:30.965216 -- MqttConnectionBase::_onError - calling disconnected callback flutter: 2023-02-26 10:02:30.966716 -- MqttConnectionBase::_onDone - calling disconnected callback flutter: 2023-02-26 10:02:30.968456 -- MqttConnectionHandlerBase::autoReconnect - attempting reconnection flutter: 2023-02-26 10:02:30.968675 -- MqttConnectionHandlerBase::connect - server 10.211.55.7, port 1883 flutter: 2023-02-26 10:02:30.968732 -- MqttSynchronousServerConnectionHandler::internalConnect entered flutter: 2023-02-26 10:02:30.968787 -- MqttSynchronousServerConnectionHandler::internalConnect - initiating connection try 0, auto reconnect in progress true flutter: 2023-02-26 10:02:30.968842 -- MqttSynchronousServerConnectionHandler::internalConnect - calling connectAuto flutter: 2023-02-26 10:02:30.969189 -- MqttNormalConnection::connectAuto - entered flutter: 2023-02-26 10:02:30.971560 -- MqttConnectionHandlerBase::autoReconnect entered in the same second as the send fail is detected, I'm assuming the 60 seconds must be when it hangs on the socket as the first thing it tries to do is send a connect message although there is no timestamp on the exception.

— Reply to this email directly, view it on GitHub https://github.com/shamblett/mqtt5_client/issues/51#issuecomment-1446287369, or unsubscribe https://github.com/notifications/unsubscribe-auth/AK6S42RUW7BVUIFPZUS6AFTWZSQXRANCNFSM6AAAAAAVH5OFLM. You are receiving this because you authored the thread.

shamblett commented 1 year ago

Unfortunately not, as I say there is no setting for this that I can see through the Dart API. I could be wrong here of course, you could try the Google guys on the dart-sdk repository here they should know more, I can't believe people haven't raised this before.

shamblett commented 1 year ago

I've just realised I have been giving you duff information, the keep alive functionality I've described above whereby the client disconnects on failure to receive ping responses has not been applied to this package, it was applied to the mqtt_client package under cover if its issue 299, not this package which is the mqtt5_client.

I have outstanding issues on this client to apply this fix but not yet got round to it.

I think the first thing to do is align the behaviour of this client with the mqtt_client package for keep alive.

Note, unless you specifically need MQTT 5 features you may be better of using the mqtt_client, its API is the same a sthis client.

jonny7737 commented 1 year ago

Thank you.

I have converted from mqtt5_client TO mqtt_client. The conversion was simple enough - though the APIs are different (personal preference: mqtt5 package seems to have a cleaner API).

The timeout issue has been eliminated in my limited testing in the last half hour or so.

Thank you for your efforts.

On Feb 28, 2023, at 2:48 AM, Steve Hamblett @.***> wrote:

I've just realised I have been giving you duff information, the keep alive functionality I've described above whereby the client disconnects on failure to receive ping responses has not been applied to this package, it was applied to the mqtt_client https://pub.dev/packages/mqtt_client package under cover if its issue 299 https://github.com/shamblett/mqtt_client/issues/299, not this package which is the mqtt5_client.

I have outstanding issues on this client to apply this fix but not yet got round to it.

I think the first thing to do is align the behaviour of this client with the mqtt_client package for keep alive.

Note, unless you specifically need MQTT 5 features you may be better of using the mqtt_client, its API is the same a sthis client.

— Reply to this email directly, view it on GitHub https://github.com/shamblett/mqtt5_client/issues/51#issuecomment-1447791307, or unsubscribe https://github.com/notifications/unsubscribe-auth/AK6S42UZYWW2FSN4X3EEO3LWZW3XTANCNFSM6AAAAAAVH5OFLM. You are receiving this because you authored the thread.

lucasjinreal commented 9 months ago

Hello, I also got some timeout issue, how to resolve it?

the client connect with server only got keepAlive=0.

flutter: 2023-11-19 21:43:35.775956 -- MqttServerConnection::_onData - MESSAGE RECEIVED -> MQTTMessage of type MqttMessageType.connectAck MessageType = MqttMessageType.connectAck Duplicate = false Retain = false Qos = atMostOnce Size = 6 Session Present = true Connect Reason Code = success Session Expiry Interval = 0 Receive Maximum = 1024 Maximum QoS = 2 Retain Available = false Maximum Packet Size = 0 Assigned client Identifier = null Topic Alias Maximum = 0 Reason String = null Wildcard Subscription Available = true Subscription Identifiers Available = true Shared Subscription Available = true broker Keep Alive = 0 Response Information = null broker Reference = null Authentication Method = null

shamblett commented 9 months ago

From the MQTT5 spec -

Keep Alive value of 0 has the effect of turning off the Keep Alive mechanism. If Keep Alive is 0 the Client is not obliged to send MQTT Control Packets on any particular schedule.

When received from the broker. So this should be having no effect, why did you thinlk it did?

If you need to know the meanings of any of these flags or behaviour of the MQTT5 protocol pleasebconsult the spec.

lucasjinreal commented 9 months ago

I got client connected and then disconnected imediately. the server side saids there a a too small keepAlive value, how should I fix this (it shouldn't be server issue either the client lib issue, there mightbe some params I missed)