From: Roger A. Light Date: Sat, 7 Jun 2014 20:00:05 +0000 (+0100) Subject: Add support for "session present" in CONNACK and on_connect. X-Git-Tag: v1.0~1^2~2 X-Git-Url: https://git.michaelhowe.org/gitweb/?a=commitdiff_plain;h=713955bd6123059044d928526d01d3aa4f8b16ca;p=packages%2Fp%2Fpaho-mqtt.git Add support for "session present" in CONNACK and on_connect. Change-Id: Icbcb603f4e5f42ff2fa35fb780ba5410248c1db0 --- diff --git a/README.rst b/README.rst index ddc5149..e93611d 100644 --- a/README.rst +++ b/README.rst @@ -82,7 +82,7 @@ Here is a very simple example that subscribes to the broker $SYS topic tree and import paho.mqtt.client as mqtt # The callback for when the client receives a CONNACK response from the server. - def on_connect(client, userdata, rc): + def on_connect(client, userdata, flags, rc): print("Connected with result code "+str(rc)) # Subscribing in on_connect() means that if we lose the connection and @@ -566,7 +566,7 @@ on_connect() :: - on_connect(client, userdata, rc) + on_connect(client, userdata, flags, rc) Called when the broker responds to our connection request. @@ -576,9 +576,19 @@ client userdata the private user data as set in ``Client()`` or ``userdata_set()`` +flags + response flags sent by the broker rc the connection result + +flags is a dict that contains response flags from the broker: + flags['session present'] - this flag is useful for clients that are + using clean session set to 0 only. If a client with clean + session=0, that reconnects to a broker that it has previously + connected to, this flag indicates whether the broker still has the + session information for the client. If 1, the session still exists. + The value of rc indicates success or not: 0: Connection successful @@ -594,7 +604,7 @@ Example :: - def on_connect(client, userdata, rc): + def on_connect(client, userdata, flags, rc): print("Connection returned result: "+connack_string(rc)) mqttc.on_connect = on_connect diff --git a/examples/mqtt_clear_retain.py b/examples/mqtt_clear_retain.py index dc88a4b..13f5754 100755 --- a/examples/mqtt_clear_retain.py +++ b/examples/mqtt_clear_retain.py @@ -31,7 +31,7 @@ except ImportError: final_mid = 0 -def on_connect(mqttc, userdata, rc): +def on_connect(mqttc, userdata, flags, rc): if userdata == True: print("rc: "+str(rc)) diff --git a/examples/session_present.py b/examples/session_present.py new file mode 100755 index 0000000..b5e2271 --- /dev/null +++ b/examples/session_present.py @@ -0,0 +1,68 @@ +#!/usr/bin/python + +# Copyright (c) 2014 Roger Light +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Distribution License v1.0 +# which accompanies this distribution. +# +# The Eclipse Distribution License is available at +# http://www.eclipse.org/org/documents/edl-v10.php. +# +# Contributors: +# Roger Light - initial implementation +# Copyright (c) 2014 Roger Light +# All rights reserved. + +# This demonstrates the session present flag when connecting. + +import sys +try: + import paho.mqtt.client as mqtt +except ImportError: + # This part is only required to run the example from within the examples + # directory when the module itself is not installed. + # + # If you have the module installed, just use "import paho.mqtt.client" + import os + import inspect + cmd_subfolder = os.path.realpath(os.path.abspath(os.path.join(os.path.split(inspect.getfile( inspect.currentframe() ))[0],"../src"))) + if cmd_subfolder not in sys.path: + sys.path.insert(0, cmd_subfolder) + import paho.mqtt.client as mqtt + +def on_connect(mqttc, obj, flags, rc): + if obj == 0: + print("First connection:") + elif obj == 1: + print("Second connection:") + elif obj == 2: + print("Third connection (with clean session=True):") + print(" Session present: "+str(flags['session present'])) + print(" Connection result: "+str(rc)) + mqttc.disconnect() + +def on_disconnect(mqttc, obj, rc): + mqttc.user_data_set(obj+1) + if obj == 0: + mqttc.reconnect() + +def on_log(mqttc, obj, level, string): + print(string) + +mqttc = mqtt.Client(client_id="asdfj", clean_session=False) +mqttc.on_connect = on_connect +mqttc.on_disconnect = on_disconnect +# Uncomment to enable debug messages +#mqttc.on_log = on_log +mqttc.user_data_set(0) +mqttc.connect("test.mosquitto.org", 1883, 60) + +mqttc.loop_forever() + +# Clear session +mqttc = mqtt.Client(client_id="asdfj", clean_session=True) +mqttc.on_connect = on_connect +mqttc.user_data_set(2) +mqttc.connect("test.mosquitto.org", 1883, 60) +mqttc.loop_forever() diff --git a/examples/sub-class.py b/examples/sub-class.py index 20e6fe4..1bc9b43 100755 --- a/examples/sub-class.py +++ b/examples/sub-class.py @@ -37,7 +37,7 @@ class MyMQTTClass: self._mqttc.on_publish = self.mqtt_on_publish self._mqttc.on_subscribe = self.mqtt_on_subscribe - def mqtt_on_connect(self, mqttc, obj, rc): + def mqtt_on_connect(self, mqttc, obj, flags, rc): print("rc: "+str(rc)) def mqtt_on_message(self, mqttc, obj, msg): diff --git a/examples/sub-srv.py b/examples/sub-srv.py index b5103a0..aa731d1 100755 --- a/examples/sub-srv.py +++ b/examples/sub-srv.py @@ -31,7 +31,7 @@ except ImportError: sys.path.insert(0, cmd_subfolder) import paho.mqtt.client as mqtt -def on_connect(mqttc, obj, rc): +def on_connect(mqttc, obj, flags, rc): print "Connected to %s:%s" % (mqttc._host, mqttc._port) def on_message(mqttc, obj, msg): diff --git a/examples/sub.py b/examples/sub.py index 0b121eb..c7c233c 100755 --- a/examples/sub.py +++ b/examples/sub.py @@ -31,7 +31,7 @@ except ImportError: sys.path.insert(0, cmd_subfolder) import paho.mqtt.client as mqtt -def on_connect(mqttc, obj, rc): +def on_connect(mqttc, obj, flags, rc): print("rc: "+str(rc)) def on_message(mqttc, obj, msg): diff --git a/src/paho/mqtt/client.py b/src/paho/mqtt/client.py index 1f75483..2f47861 100755 --- a/src/paho/mqtt/client.py +++ b/src/paho/mqtt/client.py @@ -318,7 +318,7 @@ class Client(object): broker. To use a callback, define a function and then assign it to the client: - def on_connect(client, userdata, rc): + def on_connect(client, userdata, flags, rc): print("Connection returned " + str(rc)) client.on_connect = on_connect @@ -330,15 +330,22 @@ class Client(object): The callbacks: - on_connect(client, userdata, rc): called when the broker responds to our connection - request. The value of rc determines success or not: - 0: Connection successful - 1: Connection refused - incorrect protocol version - 2: Connection refused - invalid client identifier - 3: Connection refused - server unavailable - 4: Connection refused - bad username or password - 5: Connection refused - not authorised - 6-255: Currently unused. + on_connect(client, userdata, flags, rc): called when the broker responds to our connection + request. + flags is a dict that contains response flags from the broker: + flags['session present'] - this flag is useful for clients that are + using clean session set to 0 only. If a client with clean + session=0, that reconnects to a broker that it has previously + connected to, this flag indicates whether the broker still has the + session information for the client. If 1, the session still exists. + The value of rc determines success or not: + 0: Connection successful + 1: Connection refused - incorrect protocol version + 2: Connection refused - invalid client identifier + 3: Connection refused - server unavailable + 4: Connection refused - bad username or password + 5: Connection refused - not authorised + 6-255: Currently unused. on_disconnect(client, userdata, rc): called when the client disconnects from the broker. The rc parameter indicates the disconnection state. If MQTT_ERR_SUCCESS @@ -1904,22 +1911,35 @@ class Client(object): if len(self._in_packet['packet']) != 2: return MQTT_ERR_PROTOCOL - (resvd, result) = struct.unpack("!BB", self._in_packet['packet']) + (flags, result) = struct.unpack("!BB", self._in_packet['packet']) if result == CONNACK_REFUSED_PROTOCOL_VERSION and self._protocol == MQTTv311: - self._easy_log(MQTT_LOG_DEBUG, "Received CONNACK ("+str(resvd)+", "+str(result)+"), attempting downgrade to MQTT v3.1.") + self._easy_log(MQTT_LOG_DEBUG, "Received CONNACK ("+str(flags)+", "+str(result)+"), attempting downgrade to MQTT v3.1.") # Downgrade to MQTT v3.1 self._protocol = MQTTv31 return self.reconnect() - self._easy_log(MQTT_LOG_DEBUG, "Received CONNACK ("+str(resvd)+", "+str(result)+")") + if result == 0: + self._state = mqtt_cs_connected + + self._easy_log(MQTT_LOG_DEBUG, "Received CONNACK ("+str(flags)+", "+str(result)+")") self._callback_mutex.acquire() if self.on_connect: self._in_callback = True - self.on_connect(self, self._userdata, result) + + if sys.version_info[0] < 3: + argcount = self.on_connect.func_code.co_argcount + else: + argcount = self.on_connect.__code__.co_argcount + + if argcount == 3: + self.on_connect(self, self._userdata, result) + else: + flags_dict = dict() + flags_dict['session present'] = flags & 0x01 + self.on_connect(self, self._userdata, flags_dict, result) self._in_callback = False self._callback_mutex.release() if result == 0: - self._state = mqtt_cs_connected return MQTT_ERR_SUCCESS elif result > 0 and result < 6: return MQTT_ERR_CONN_REFUSED diff --git a/src/paho/mqtt/publish.py b/src/paho/mqtt/publish.py index 89aae28..6a0e045 100644 --- a/src/paho/mqtt/publish.py +++ b/src/paho/mqtt/publish.py @@ -49,7 +49,7 @@ def _do_publish(c): c.publish(topic, payload, qos, retain) -def _on_connect(c, userdata, rc): +def _on_connect(c, userdata, flags, rc): """Internal callback""" _do_publish(c) diff --git a/test/lib/python/01-con-discon-success.test b/test/lib/python/01-con-discon-success.test index 489fece..b150f9c 100755 --- a/test/lib/python/01-con-discon-success.test +++ b/test/lib/python/01-con-discon-success.test @@ -10,7 +10,7 @@ from struct import * import paho.mqtt.client as mqtt -def on_connect(mqttc, obj, rc): +def on_connect(mqttc, obj, flags, rc): if rc != 0: exit(rc) else: diff --git a/test/lib/python/01-keepalive-pingreq.test b/test/lib/python/01-keepalive-pingreq.test index 8dd7512..7a092b5 100755 --- a/test/lib/python/01-keepalive-pingreq.test +++ b/test/lib/python/01-keepalive-pingreq.test @@ -10,7 +10,7 @@ from struct import * import paho.mqtt.client as mqtt -def on_connect(mqttc, obj, rc): +def on_connect(mqttc, obj, flags, rc): if rc != 0: exit(rc) diff --git a/test/lib/python/02-subscribe-qos0.test b/test/lib/python/02-subscribe-qos0.test index b964f62..001e0f8 100755 --- a/test/lib/python/02-subscribe-qos0.test +++ b/test/lib/python/02-subscribe-qos0.test @@ -10,7 +10,7 @@ from struct import * import paho.mqtt.client as mqtt -def on_connect(mqttc, obj, rc): +def on_connect(mqttc, obj, flags, rc): if rc != 0: exit(rc) else: diff --git a/test/lib/python/02-subscribe-qos1.test b/test/lib/python/02-subscribe-qos1.test index 6fc247f..3400dc5 100755 --- a/test/lib/python/02-subscribe-qos1.test +++ b/test/lib/python/02-subscribe-qos1.test @@ -10,7 +10,7 @@ from struct import * import paho.mqtt.client as mqtt -def on_connect(mqttc, obj, rc): +def on_connect(mqttc, obj, flags, rc): if rc != 0: exit(rc) else: diff --git a/test/lib/python/02-subscribe-qos2.test b/test/lib/python/02-subscribe-qos2.test index 9d52faa..2776317 100755 --- a/test/lib/python/02-subscribe-qos2.test +++ b/test/lib/python/02-subscribe-qos2.test @@ -10,7 +10,7 @@ from struct import * import paho.mqtt.client as mqtt -def on_connect(mqttc, obj, rc): +def on_connect(mqttc, obj, flags, rc): if rc != 0: exit(rc) else: diff --git a/test/lib/python/02-unsubscribe.test b/test/lib/python/02-unsubscribe.test index 4a52779..eab5e8a 100755 --- a/test/lib/python/02-unsubscribe.test +++ b/test/lib/python/02-unsubscribe.test @@ -10,7 +10,7 @@ from struct import * import paho.mqtt.client as mqtt -def on_connect(mqttc, obj, rc): +def on_connect(mqttc, obj, flags, rc): if rc != 0: exit(rc) else: diff --git a/test/lib/python/03-publish-b2c-qos1.test b/test/lib/python/03-publish-b2c-qos1.test index ef6d100..3b553df 100755 --- a/test/lib/python/03-publish-b2c-qos1.test +++ b/test/lib/python/03-publish-b2c-qos1.test @@ -27,7 +27,7 @@ def on_message(mqttc, obj, msg): exit(1) exit(0) -def on_connect(mqttc, obj, rc): +def on_connect(mqttc, obj, flags, rc): if rc != 0: print("Connect failed ("+str(rc)+")") exit(rc) diff --git a/test/lib/python/03-publish-b2c-qos2.test b/test/lib/python/03-publish-b2c-qos2.test index 4540b55..da8da76 100755 --- a/test/lib/python/03-publish-b2c-qos2.test +++ b/test/lib/python/03-publish-b2c-qos2.test @@ -30,7 +30,7 @@ def on_message(mqttc, obj, msg): run = 0 -def on_connect(mqttc, obj, rc): +def on_connect(mqttc, obj, flags, rc): if rc != 0: exit(rc) diff --git a/test/lib/python/03-publish-c2b-qos1-disconnect.test b/test/lib/python/03-publish-c2b-qos1-disconnect.test index 8fc4a1d..a409cb9 100755 --- a/test/lib/python/03-publish-c2b-qos1-disconnect.test +++ b/test/lib/python/03-publish-c2b-qos1-disconnect.test @@ -11,7 +11,7 @@ import paho.mqtt.client as mqtt sent_mid = -1 -def on_connect(mqttc, obj, rc): +def on_connect(mqttc, obj, flags, rc): global sent_mid if rc != 0: exit(rc) diff --git a/test/lib/python/03-publish-c2b-qos1-timeout.test b/test/lib/python/03-publish-c2b-qos1-timeout.test index 26a24ca..b691267 100755 --- a/test/lib/python/03-publish-c2b-qos1-timeout.test +++ b/test/lib/python/03-publish-c2b-qos1-timeout.test @@ -11,7 +11,7 @@ import paho.mqtt.client as mqtt sent_mid = -1 -def on_connect(mqttc, obj, rc): +def on_connect(mqttc, obj, flags, rc): global sent_mid if rc != 0: exit(rc) diff --git a/test/lib/python/03-publish-c2b-qos2-disconnect.test b/test/lib/python/03-publish-c2b-qos2-disconnect.test index d4c6f69..f3bf38b 100755 --- a/test/lib/python/03-publish-c2b-qos2-disconnect.test +++ b/test/lib/python/03-publish-c2b-qos2-disconnect.test @@ -11,7 +11,7 @@ import paho.mqtt.client as mqtt first_connection = 1 -def on_connect(mqttc, obj, rc): +def on_connect(mqttc, obj, flags, rc): global first_connection if rc != 0: exit(rc) diff --git a/test/lib/python/03-publish-c2b-qos2-timeout.test b/test/lib/python/03-publish-c2b-qos2-timeout.test index 892204b..17f8b7c 100755 --- a/test/lib/python/03-publish-c2b-qos2-timeout.test +++ b/test/lib/python/03-publish-c2b-qos2-timeout.test @@ -10,7 +10,7 @@ from struct import * import paho.mqtt.client as mqtt -def on_connect(mqttc, obj, rc): +def on_connect(mqttc, obj, flags, rc): if rc != 0: exit(rc) else: diff --git a/test/lib/python/03-publish-qos0-no-payload.test b/test/lib/python/03-publish-qos0-no-payload.test index f247f40..fa44204 100755 --- a/test/lib/python/03-publish-qos0-no-payload.test +++ b/test/lib/python/03-publish-qos0-no-payload.test @@ -11,7 +11,7 @@ import paho.mqtt.client as mqtt sent_mid = -1 -def on_connect(mqttc, obj, rc): +def on_connect(mqttc, obj, flags, rc): global sent_mid if rc != 0: exit(rc) diff --git a/test/lib/python/03-publish-qos0.test b/test/lib/python/03-publish-qos0.test index 0cbb7da..af4f892 100755 --- a/test/lib/python/03-publish-qos0.test +++ b/test/lib/python/03-publish-qos0.test @@ -11,7 +11,7 @@ import paho.mqtt.client as mqtt sent_mid = -1 -def on_connect(mqttc, obj, rc): +def on_connect(mqttc, obj, flags, rc): global sent_mid if rc != 0: exit(rc) diff --git a/test/lib/python/04-retain-qos0.test b/test/lib/python/04-retain-qos0.test index 1564648..4a46249 100755 --- a/test/lib/python/04-retain-qos0.test +++ b/test/lib/python/04-retain-qos0.test @@ -10,7 +10,7 @@ from struct import * import paho.mqtt.client as mqtt -def on_connect(mqttc, obj, rc): +def on_connect(mqttc, obj, flags, rc): if rc != 0: exit(rc) else: diff --git a/test/lib/python/08-ssl-connect-cert-auth.test b/test/lib/python/08-ssl-connect-cert-auth.test index a7b4835..8f2eba8 100755 --- a/test/lib/python/08-ssl-connect-cert-auth.test +++ b/test/lib/python/08-ssl-connect-cert-auth.test @@ -13,7 +13,7 @@ if sys.version < '2.7': print("WARNING: SSL/TLS not supported on Python 2.6") exit(0) -def on_connect(mqttc, obj, rc): +def on_connect(mqttc, obj, flags, rc): if rc != 0: exit(rc) else: diff --git a/test/lib/python/08-ssl-connect-no-auth.test b/test/lib/python/08-ssl-connect-no-auth.test index 1f30937..ce48e03 100755 --- a/test/lib/python/08-ssl-connect-no-auth.test +++ b/test/lib/python/08-ssl-connect-no-auth.test @@ -13,7 +13,7 @@ if sys.version < '2.7': print("WARNING: SSL/TLS not supported on Python 2.6") exit(0) -def on_connect(mqttc, obj, rc): +def on_connect(mqttc, obj, flags, rc): if rc != 0: exit(rc) else: diff --git a/test/lib/python/08-ssl-fake-cacert.test b/test/lib/python/08-ssl-fake-cacert.test index f876a10..2afc198 100755 --- a/test/lib/python/08-ssl-fake-cacert.test +++ b/test/lib/python/08-ssl-fake-cacert.test @@ -14,7 +14,7 @@ if sys.version < '2.7': print("WARNING: SSL/TLS not supported on Python 2.6") exit(0) -def on_connect(mqttc, obj, rc): +def on_connect(mqttc, obj, flags, rc): exit(1) mqttc = mqtt.Client("08-ssl-fake-cacert")