emqtt 是采用Erlang语言开发,全面支持MQTT V3.1.1协议,支持集群和大规模连接的开源MQTT消息服务器,主要应用于物联网,移动互联网的消息服务。在Python语言中可以使用第三方库nyamuk提供的api实现emqtt的访问连接,实现订阅/发布消息队列服务(目前该第三方库只支持Python2 版本)。
/
,windows下使用\
).\bin\emqttd console # 控制台启动emqtt服务
.\bin\emqttd start # 守护进程启动emqtt服务
pip install nyamuk
subscribe.py
import sys
from nyamuk import *
# nloop 函数:发送发布消息→读取订阅消息→队列形式返回一个消息
def nloop(client):
client.packet_write() # flush write buffer (messages sent to MQTT server)
client.loop() # fill read buffer (enqueue received messages)
return client.pop_event() # return 1st received message (dequeued)
client = Nyamuk("test_nyamuk", server="localhost")
# Nyamuk:
# def __init__(self, client_id, username = None, password = None,
# server = "localhost", port = None, keepalive = NC.KEEPALIVE_VAL,
# log_level = logging.DEBUG,
# ssl = False, ssl_opts=[]):
ret = client.connect(version=3)
ret = nloop(client) # ret should be EventConnack object
# 连接确认
if not isinstance(ret, EventConnack) or ret.ret_code != 0:
print ('connection failed'; sys.exit(1))
# 订阅主题
client.subscribe('foo/bar', qos=1)
ret = nloop(client)
# 订阅主题确认
if not isinstance(ret, EventSuback):
print 'SUBACK not received'; sys.exit(2)
print 'granted qos is', ret.granted_qos[0]
# 开始侦听消息
try:
while True:
evt = nloop(client)
if isinstance(evt, EventPublish):
print 'we received a message: {0} (topic= {1})'.format(evt.msg.payload, evt.msg.topic)
# received message is either qos 0 or 1
# in case of qos 1, we must send back PUBACK message with same packet-id
if evt.msg.qos == 1:
client.puback(evt.msg.mid)
except KeyboardInterrupt:
pass
client.disconnect()
publish.py
import sys
from nyamuk import *
def nloop(client):
client.packet_write() # flush write buffer (messages sent to MQTT server)
client.loop() # fill read buffer (enqueue received messages)
return client.pop_event() # return 1st received message (dequeued)
client = Nyamuk("test_nyamuk", server="localhost")
ret = client.connect(version=3)
ret = nloop(client) # ret should be EventConnack object
if not isinstance(ret, EventConnack) or ret.ret_code != 0:
print 'connection failed'; sys.exit(1)
client.publish('foo/bar', 'this is a test', qos=1)
ret = nloop(client) # ret should be EventPuback
client.disconnect()
先在一个命令行窗口1运行订阅端脚本: python subscribe.py 订阅便运行在监听状态
2017-04-25 08:26:37,111 - test_nyamuk - INFO - Connecting to server ....localhost # 发起连接中
2017-04-25 08:26:37,141 - test_nyamuk - INFO - CONNACK reveived # 确认连接
2017-04-25 08:26:37,142 - test_nyamuk - INFO - SUBSCRIBE: foo/bar # 订阅主题foo/bar
2017-04-25 08:26:37,144 - test_nyamuk - INFO - SUBACK received # 订阅成功确认
granted qos is 1 # qos=0最多一次;qos=1最少一次;qos=2只有一次的传输
再开一个命令行窗口2运行发布端脚本: python publish.py
2017-04-25 08:30:42,881 - clientid - INFO - Connecting to server ....localhost
2017-04-25 08:30:42,891 - clientid - INFO - CONNACK reveived
2017-04-25 08:30:42,892 - clientid - DEBUG - Send PUBLISH # 发布主题+消息
2017-04-25 08:30:42,894 - clientid - INFO - PUBACK received # 发布成功确认
2017-04-25 08:30:42,894 - clientid - INFO - DISCONNECT # 断开连接
窗口1打印订阅消息:
2017-04-25 08:27:54,075 - test_nyamuk - DEBUG - PUBLISH received
we received a message: this is a test (topic= foo/bar)
2017-04-25 08:27:54,075 - test_nyamuk - DEBUG - Received PUBLISH(dup = 0,qos=1,retain=0
2017-04-25 08:27:54,075 - test_nyamuk - DEBUG - mid=1, topic=foo/bar, payloadlen=14
2017-04-25 08:27:54,075 - test_nyamuk - INFO - Send PUBACK (msgid=1)
此外窗口1还有2分钟一次的心跳机制:
2017-04-25 08:34:42,986 - test_nyamuk - DEBUG - SEND PINGREQ
2017-04-25 08:34:42,987 - test_nyamuk - DEBUG - PINGRESP received
2017-04-25 08:36:43,033 - test_nyamuk - DEBUG - SEND PINGREQ
2017-04-25 08:36:43,036 - test_nyamuk - DEBUG - PINGRESP received
至此,确认OK啦~