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

client.disconnect() does not disconnect the client if no connection #214

Open
RockyGitHub opened this issue Nov 30, 2023 · 3 comments
Open

Comments

@RockyGitHub
Copy link

RockyGitHub commented Nov 30, 2023

Hello!

I've been trying to do some logic involving the AsyncClient and calling disconnect().

I am seeing consistently that that after calling client.disconnect().wait_timeout(), when there is no internet connection, a subsequent call to client.is_connected() returns true.
Not until the client times itself out, outside of the call to disconnect().

Is this intended?

Thank you!
-Rocky

@fpagliughi
Copy link
Contributor

Definitely not the _desired_behavior.

Did the disconnect .wait_timeout() actually timeout? Or did it succeed or otherwise fail with an error?
If it timed out or otherwise failed, then, internally, it might not have figured out that it is off-line. Yet.

Also was this done with Ethernet (hardwired) or WiFi (wireless). With wireless, it seems like if usually takes a long time for the OS to tell the app that the connection was lost.

Either way on all that, I have gotten a few reports that is_connected() is returning the wrong result. Mostly like you say: It's claiming to be connected when it's not. This is mostly an upstream library issue, but I'll dig into it and report it upstream.

@RockyGitHub
Copy link
Author

RockyGitHub commented Nov 30, 2023

The wait_timeout() does indeed timeout, it fails with an error since it doesn't get a server response in this particular case.

This was on WiFi. It does take a while for the client to realize it has lost connection, I figured this was due to my default keep_alive setting at 60s.

Yeah I don't think it's your library, fortunately or unfortunately lol. However, the call to disconnect() immediately calls the message_callback with the None value, so I can work with that to avoid using the client.is_connected(). It's certainly a lot less convenient though. But thank you for providing the callback functionality :)

btw, the way I am mocking a loss of internet connection is by doing sudo ip route add mqtt.ip.address via 127.0.0.1 and then I restore it with sudo ip route del mqtt.ip.address

@fpagliughi
Copy link
Contributor

Yeah, it can be difficult for any network application, especially if the OS never tells it that the interface or network is down. It can be even worse for Cell and Satellite modems, which I used to use a lot for MQTT.

The KeepAlive is a failsafe for these occasions. If the underlying TCP connection is jammed up, the one way you know for sure that you still have a connection to the server is to send a request and get a proper response. But remember that the requested keep alive (60sec, in your case) is the time at which the client should send the ping request (PINGREQ), but I'm pretty sure it's up to the client to decide how long to wait for the response (PINGRSP) before declaring the connection lost and shut it down.

On the broker side, it expects to get a packet from the client within the keep alive time that that particular client requested. But fairly universally (as per the MQTT spec), the server will wait an additional 50% of the requested time (90sec total in your case) before declaring the client lost and closing the connection.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants