Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MQTT over websocket in python

is there any support in python to subscribe on mqtt broker with port 8080

 import sys
 import paho.mqtt.client as mqtt

 def on_connect(mqttc, obj, flags, rc):
     print("rc: "+str(rc))

 def on_message(mqttc, obj, msg):
     print(msg.topic+" "+str(msg.qos)+" "+str(msg.payload))

 def on_publish(mqttc, obj, mid):
     print("mid: "+str(mid))

 def on_subscribe(mqttc, obj, mid, granted_qos):
     print("Subscribed: "+str(mid)+" "+str(granted_qos))

 def on_log(mqttc, obj, level, string):
     print(string)

 mqttc = mqtt.Client()   
 mqttc.on_message = on_message
 mqttc.on_connect = on_connect
 mqttc.on_publish = on_publish
 mqttc.on_subscribe = on_subscribe
 mqttc.connect("test.mosquitto.org", 8080, 60)
 mqttc.subscribe("test/iot", 0)

 mqttc.loop_forever()

i can not connect with this code. Mosquitto has websocket support at port 8080 but this paho library does not work for it. any solution for python? i am using python 2.7 on windows 10.

like image 348
Smit Gardhariya Avatar asked Dec 01 '22 16:12

Smit Gardhariya


2 Answers

The Paho MQTT module introduced websocket support some days ago. I don't think it is released yet, but you can install from the master under Linux branch using

pip install git+git://github.com/eclipse/paho.mqtt.python.git

Also works under windows. (Thanks for info from the comments)

You can use the websockets as transport by connecting with

mqttc = mqtt.Client(transport="websockets")

UPDATE:

If you try to use the websocket protocol with the python client because you also need to connect a browser client (for example MQTT.js) then you can also configure mosquitto to listen to websockets and the normal mqtt protocol.

Simply create a configuration file for example in

/etc/mosquitto/mosquitto.conf

with the following contents:

listener 1883
protocol mqtt

listener 9001
protocol websockets

Then you can then run mosquitto with

mosquitto -c /etc/mosquitto/mosquitto.conf

You should see similar output:

1469015320: mosquitto version 1.4.8 (build date 2016-05-3112:07:40+0200) starting
1469015320: Config loaded from /etc/mosquitto/mosquitto1.conf.
1469015320: Opening ipv4 listen socket on port 1883.
1469015320: Opening ipv6 listen socket on port 1883.
1469015320: Opening websockets listen socket on port 9001.

Your python client then connects to port 1883 and the browser client to 9001

You can use what-mqtt browser client to test the websocket listener. Just point it to ws://localhost:9001

like image 82
Fl0v0 Avatar answered Dec 04 '22 08:12

Fl0v0


Between Feb and now the paho.mqtt.python codebase has been fixed. Just add transport='websockets' as Fl0v0 suggested, it simply works. Below is the full code which subscribes to everything or everything under $SYS/. The code tested is on the master branch with commit hash e56f913 on June 3 of 2016.

#!/usr/bin/python

import sys
import paho.mqtt.client as mqtt

def on_connect(mqttc, obj, flags, rc):
    print("rc: "+str(rc))

def on_message(mqttc, obj, msg):
    print(msg.topic+" "+str(msg.qos)+" "+str(msg.payload))

def on_publish(mqttc, obj, mid):
    print("mid: "+str(mid))

def on_subscribe(mqttc, obj, mid, granted_qos):
    print("Subscribed: "+str(mid)+" "+str(granted_qos))

def on_log(mqttc, obj, level, string):
    print(string)

mqttc = mqtt.Client(transport='websockets')   
mqttc.on_message = on_message
mqttc.on_connect = on_connect
mqttc.on_publish = on_publish
mqttc.on_subscribe = on_subscribe

mqttc.connect("test.mosquitto.org", 8080, 60)

mqttc.subscribe("#", 0)
#mqttc.subscribe("$SYS/#", 0)

mqttc.loop_forever()

Update: The code above does not work on Windows 7 with python 2.7.6 that I tested with, by invoking from one version of Cygwin (not the cygwin python though). None of the topic "#" or "$SYS/#" gives any published message back.

Instead, pub or sub to solid topics works as the example follows. Patch paho.mqtt.python examples/pub-single.py and examples/sub-simple.py. Then run sub-simple.py in one terminal. Run pub-single.py in another terminal, twice. The subscriber terminal will print out two messages published by the publisher.

Patch to examples/pub-single.py:

-publish.single("paho/test/single", "boo", hostname="test.mosquitto.org")
+publish.single("/HelloWorld", "boo", hostname="test.mosquitto.org",
+               port=8080, transport='websockets')

Patch to examples/sub-simple.py:

-topics = ['#']
+topics = ['/HelloWorld']

-m = subscribe.simple(topics, hostname="iot.eclipse.org", retained=False, msg_count=2)
+m = subscribe.simple(topics, hostname="test.mosquitto.org",
+                         retained=False, msg_count=2,
+                         port=8080, transport='websockets')
like image 25
minghua Avatar answered Dec 04 '22 07:12

minghua