-
Notifications
You must be signed in to change notification settings - Fork 52
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 remains active after disconnect() #79
Comments
@stefangotz Thanks for letting us know. Setup is strange indeed, we didn't perform tests like this. I will try to figure out what went wrong in latest version. |
Env: Win7 64 /python3.7.5 /Tornado6 /gmqtt 0.5.1 import socket
import asyncio
import logging
from tornado.ioloop import IOLoop,PeriodicCallback
import gmqtt
class GMQTT(object):
def __init__(self):
self.log = logging.getLogger(__name__)
self.log.setLevel(logging.DEBUG)
self.mqtt_broker_host = "localhost"
self.mqtt_broker_port = 1883
self.dst_topic = "a/b"
self.period_callback = None
self.loop = IOLoop.instance() #
## self.loop.asyncio_loop ==
mqtt_client = gmqtt.Client(client_id="xxxx" )
mqtt_client.on_connect = self.on_connect
mqtt_client.on_message = self.on_message
mqtt_client.on_disconnect = self.on_disconnect
#mqtt_client.on_subscribe = self.on_subscribe
self.mqtt_client = mqtt_client
self.index = 0
async def period_check(self):
'''
send msg periodically
'''
if self.mqtt_client.is_connected:
self.mqtt_client.publish(self.dst_topic, f"Hello:{self.index}".encode() )
self.index +=1
def on_message(self, client, topic, payload, qos, properties):
self.log.info(f'MQTT.Recv {client._client_id}] TOPIC: {topic} PAYLOAD: {payload} QOS: {qos} PROPERTIES: {properties}'
)
def on_connect(self, client, flags, rc, properties):
self.log.info('[MQTT.CONNECTED {}]'.format(client._client_id))
self.mqtt_client.subscribe( self.dst_topic )
def on_disconnect(self, client, packet, exc=None):
self.log.info('[MQTT.DISCONNECTED {}]'.format(client._client_id))
async def unreg(self):
if self.mqtt_client.is_connected:
self.mqtt_client.unsubscribe( self.dst_topic )
await self.mqtt_client.disconnect()
async def reg(self):
await self.mqtt_client.connect(self.mqtt_broker_host)
if not self.period_callback :
self.period_callback = PeriodicCallback(self.period_check,
callback_time=1000) #Unit:milliseconds
if not self.period_callback.is_running():
self.period_callback.start()
if __name__ == "__main__":
c = GMQTT()
c.loop.run_sync(c.reg)
c.loop.call_later(10, c.unreg)
c.loop.start() Result:
|
The reason for this problem is that after disconnect() , a CONNACK message received , which cause link connected again! track stack:
|
Hi @honglei Thanks for your investigation. We founded an error in our reconnection logic and will think how to fix it in the best way. We will fix this behavior in next version (approximately tomorrow). |
@honglei please, check version 0.5.2 |
@Lenka42 version 0.5.2 solved this problem, Thanks! |
@stefangotz does the new version solve also the problem in your setup? 🙂 |
Could you please share your code improvement? |
@Lenka42 I've tried 0.5.4 and it is better, but unfortunately still not as good as 0.4.5 as far as the API is concerned. When I run the attached sample program with 0.5.4, the output is as follows:
This is an improvement over 0.5 in that the Client instance appears to become inactive after the second call-back to
At least I personally find that confusing for application developers and fairly difficult to handle nicely in application code because it feels like one can never be quite sure when a connection is really closed and it is safe to tear down all connection state. What do you think? Is that something that could be improved so that gmqtt's API makes it crystal clear to applications when connections are truly closed and an application no longer needs to expect to receive call-backs from gmqtt? |
I updated the library from version 0.5.4 to 0.6.2 and I have stumbled upon a similar problem. I can check in the mosquitto log which says: My client has a keepalive of 60 seconds and is not subscribed to any topics. |
It is a single python thread which never disconnects, and I am sure there is no other thread/client with the same client ID. |
@madhukar01 sorry, I need more details on what's going on in your case. |
Hello. Just. Restart MQTT broker. What we have: |
Hi @straga Please checkout our new version. We have been improved disconnect behavior (0.6.6); |
Hi!
My usecase is to use gmqtt with an MQTT broker over an unreliable link, so it can be unavailable for quite a bit or the MQTT TCP connection can be in weird and wonderful states. Furthermore, I need to completely shutdown and discard a gmqtt client and all its resources and tasks if it is unable to connect to such an MQTT broker.
One particular slightly strange connection state can be simulated with SSH port forwarding. On Linux and friends, the command
ssh -L 2000:localhost:1 localhost
opens local port 2000 and connects it to the closed port 1, simulating a case where you can connect to port 2000, but can't actually get data through.I've been using code roughly similar to the simplified attachment test.py.txt to make this work with v0.4.5. The attached code produces the following output with v0.4.5:
So while
client.connect()
doesn't return, that's ok because I can see from the call toon_disconnect()
that there is on connection. After callingclient.disconnect()
the client is no longer active, which is what I want.With v0.5, the output is as follows:
This indicates that after having called
client.disconnect()
the gmqtt client still has some async call-backs going on and at least with the regular API, I couldn't figure out how to make those stop.I'm not sure whether that behavior is intentional or whether I missed something, so I just wanted to let you know that it seems that v0.5.0 doesn't quite seem to serve the particular use case I'm after. Are there any plans to change this behavior again in the future?
The text was updated successfully, but these errors were encountered: