]> git.michaelhowe.org Git - packages/p/paho-mqtt.git/commitdiff
Add support for "session present" in CONNACK and on_connect.
authorRoger A. Light <roger@atchoo.org>
Sat, 7 Jun 2014 20:00:05 +0000 (21:00 +0100)
committerRoger A. Light <roger@atchoo.org>
Sat, 7 Jun 2014 20:00:05 +0000 (21:00 +0100)
Change-Id: Icbcb603f4e5f42ff2fa35fb780ba5410248c1db0

26 files changed:
README.rst
examples/mqtt_clear_retain.py
examples/session_present.py [new file with mode: 0755]
examples/sub-class.py
examples/sub-srv.py
examples/sub.py
src/paho/mqtt/client.py
src/paho/mqtt/publish.py
test/lib/python/01-con-discon-success.test
test/lib/python/01-keepalive-pingreq.test
test/lib/python/02-subscribe-qos0.test
test/lib/python/02-subscribe-qos1.test
test/lib/python/02-subscribe-qos2.test
test/lib/python/02-unsubscribe.test
test/lib/python/03-publish-b2c-qos1.test
test/lib/python/03-publish-b2c-qos2.test
test/lib/python/03-publish-c2b-qos1-disconnect.test
test/lib/python/03-publish-c2b-qos1-timeout.test
test/lib/python/03-publish-c2b-qos2-disconnect.test
test/lib/python/03-publish-c2b-qos2-timeout.test
test/lib/python/03-publish-qos0-no-payload.test
test/lib/python/03-publish-qos0.test
test/lib/python/04-retain-qos0.test
test/lib/python/08-ssl-connect-cert-auth.test
test/lib/python/08-ssl-connect-no-auth.test
test/lib/python/08-ssl-fake-cacert.test

index ddc5149e856280b95b3fe13e70b906bf23a3813b..e93611d575cf36b40149dab6414d8a1eca419661 100644 (file)
@@ -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
index dc88a4ba48f2d5f7715ae16427ebd9ec748c7d75..13f5754ae1a2e76d8454aee19a4bb6b3f72c134b 100755 (executable)
@@ -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 (executable)
index 0000000..b5e2271
--- /dev/null
@@ -0,0 +1,68 @@
+#!/usr/bin/python
+
+# Copyright (c) 2014 Roger Light <roger@atchoo.org>
+#
+# 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 <roger@atchoo.org>
+# 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()
index 20e6fe4d9ea447aa67a728944df103a9d219b65f..1bc9b439e1313bd10de4955c5b9e9fb90847a5eb 100755 (executable)
@@ -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):
index b5103a00ae0cce4a90b3219e4dbc47e910a43613..aa731d1dbca78f52ec73be2ad2a61a7e29be7687 100755 (executable)
@@ -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):
index 0b121ebae4de2b4434edb2259b3ab41477317318..c7c233ca5354a7dac45627dae9a8e06084e79955 100755 (executable)
@@ -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):
index 1f754835fa002ed262980b107744438c492c3b13..2f478610de8253e749612c82e25f63194f27d4bf 100755 (executable)
@@ -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
index 89aae28351c1d75a4c591200a1a3f573a2103829..6a0e045b883f6a0508795721d3023bccb70ccaff 100644 (file)
@@ -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)
 
index 489fece84bbeee0add0024167f5309cc4d5a6c58..b150f9c0390eb4375adfbd177b08d23ab6f1c424 100755 (executable)
@@ -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:
index 8dd751294f299205596164bc561a061dce300a12..7a092b5ad876047d22bfb3fd15ba48a86b02c48e 100755 (executable)
@@ -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)
 
index b964f627fea1fb3135755d8f77f8281c49981b43..001e0f862429ad5d2dda306b1fa0dfb90a34a02b 100755 (executable)
@@ -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:
index 6fc247f9a23d3005607a4527191ffcac6e58aa5a..3400dc5c4eab9f39600c015c5e818849dd207080 100755 (executable)
@@ -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:
index 9d52faa8b54cdbc021f92236056405e8751ff651..2776317a1bc7db7c3e9ee547b4316f483d30aaee 100755 (executable)
@@ -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:
index 4a52779f1a5597a1a9a397416cf26c03140c64d1..eab5e8a2e22b7a8ff43fb8fb756724e4d2c444c7 100755 (executable)
@@ -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:
index ef6d1006d0c070d964aa402aa3d5f6b9ba50d35e..3b553dfa0df8774ccca3cf65c3c35329c6f5eb6c 100755 (executable)
@@ -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)
index 4540b55ebaf81fcfee411128add268ec84f0eaa8..da8da765b1e6d90dbf11d8b6f1428d6347c9a46c 100755 (executable)
@@ -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)
 
index 8fc4a1d5082f4e1b84e50cac401213d49d8a5377..a409cb98f3adb869242b69a0316959938ffa599a 100755 (executable)
@@ -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)
index 26a24ca03326aa9c3e2773045e74ff4bdc7e6f06..b691267f9ff6855f33d0bd1c5bb90df615fb9199 100755 (executable)
@@ -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)
index d4c6f6909e1c500df78d9ad4c40310ac926a468b..f3bf38be459f1214822aabb7d2b3443f8a6ac527 100755 (executable)
@@ -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)
index 892204b2225ddbb53a3b88cf45f7425f8c1c2674..17f8b7c8ce161a13c327bd4f02a6f5d3f8eb9315 100755 (executable)
@@ -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:
index f247f4094a00a2b727fed48f325c1249e86906e2..fa442046864d32a51bd4940ea898de5cf40b732b 100755 (executable)
@@ -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)
index 0cbb7da4fd29d6408a2044b314233afba3cd22cd..af4f8925f10c53930db6d6806618ed4fa0b001ce 100755 (executable)
@@ -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)
index 1564648a77c966cb5089b7d27039380ed6a8353b..4a46249d0131a5da54e9448995db63aa4906de62 100755 (executable)
@@ -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:
index a7b483574efebf62d9bc655cdbb73acbc4a38cc3..8f2eba8534bf69b6b22a34292f820d7d5dba484c 100755 (executable)
@@ -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:
index 1f30937ebd3368e6abd38a42b4b96a8531eb090f..ce48e0335990d9e2cdfde19ff7753471a5b51288 100755 (executable)
@@ -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:
index f876a10f88a1541b86d498cd85c9092ef6330617..2afc1981ffc624c74ebac02a5447cf15f8b1321d 100755 (executable)
@@ -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")