zoukankan      html  css  js  c++  java
  • Python实现MQTT接收订阅数据

    一、背景

    目前MQTT的标准组织官网:http://www.mqtt.org,里面列出了很多支持的软件相关资源。

    一个轻量级的MQTT服务器是:http://www.mosquitto.org,可以运行ARM/MIPS的嵌入式linux系统上。

    物联网常使用 “消息队列遥测传输(Message Queuing Telemetry Transport, MQTT)” 协议订阅数据,这里用Python实现从MQTT服务器订阅数据。

    首先和TCP协议比较

    首先TCP是传输层协议,实现了一个双向的通信链路。

    MQTT是基于TCP的应用层协议。(当然中间可能多一层,websocket)

    两者不在一个层级,比较谁比谁好是没有意义的。

    我们用raw TCP 也可以实现数据通信,比如发送传感器数据到服务器。为什么要用到MQTT呢 ?

    假设现在有一个物联网的应用,题主当然可以直接用TCP socket 做通信,实际上不少人也是这么做的。然后你就会发现:

    • 需要自己写确认重传的机制,因为TCP 连接说不定就断了。

    • 如果有很多个传感器(生产者),又要写代码管理这么多TCP连接呢。

    • 如果同时又有多个地方需要用到这些数据,还得写一个转发的逻辑。

    • 如果系统很复杂,参与人或公司很多,那通信格式要怎么定,怎么改,沟通成本就很大了。

    这些东西这么麻烦,又不想加班写代码,那有没有办法简便地解决呢?当然有,就是用现成的协议啦,比如MQTT。

    MQTT 提供两个核心功能:

    • 三个级别的QOS

    • 基于订阅/发布的消息转发服务。

    用了MQTT, 上面提到的这些问题就都被优雅地解决掉啦。

    其实,同类应用的很多问题,都是有一定共性的。这时候就会有一些人提出一般性的解决方式,这样大家就不用重复造轮子,同时又保证了互操作性。这就是协议存在的意义啦。

    所以一句话总结,MQTT 和其他的应用层协议,比如 HTPP, FTP, BitTorrent 协议一样,都是为了解决特定问题而生的一套方案,可以帮我们省好多事。

    二、安装部署

    环境:Python 2.7.5

              mosquitto version 1.5.8

              mosquitto is an MQTT v3.1.1 broker.

    安装安装mosquitto,这里比较省事了

    yum -y install mosquitto mosquitto-clients python-mosquitto   
    

    安装paho-mqtt,pypi上有这个库,可以自行安装

    三、测试

    启动命令: mosquitto
    server:mosquitto_pub -t test -h 127.0.0.1 -m  '{"pin":1,"value":0}'
    client:mosquitto_sub -v -t test -h 127.0.0.1 (先启动)
    

     测试结果

    [root@test ~]# mosquitto_sub -v -t test -h 127.0.0.1        
    test {"pin":1,"value":0} 

    使用脚本测试

    client.py

    #!/usr/bin/python
    
    import sys
    import datetime
    import socket, sys
    
    #======================================================        
    try:
        import paho.mqtt.client as mqtt
    except ImportError:
        print("MQTT client not find. Please install as follow:")
        print("git clone http://git.eclipse.org/gitroot/paho/org.eclipse.paho.mqtt.python.git")
        print("cd org.eclipse.paho.mqtt.python")
        print("sudo python setup.py install")
    
    # 服务器地址
    strBroker = "localhost"
    # 通信端口
    port = 1883
    # 用户名
    username = 'username'
    # 密码
    password = 'password'
    # 订阅主题名
    topic = 'topic'
    
    #======================================================
    def on_connect(mqttc, obj, rc):
        print("OnConnetc, rc: "+str(rc))
    
    def on_publish(mqttc, obj, mid):
        print("OnPublish, 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("Log:"+string)
    
    def on_message(mqttc, obj, msg):
        curtime = datetime.datetime.now()
        strcurtime = curtime.strftime("%Y-%m-%d %H:%M:%S")
        print(strcurtime + ": " + msg.topic+" "+str(msg.qos)+" "+str(msg.payload))
        on_exec(str(msg.payload))
    
    def on_exec(strcmd):
        print "Exec:",strcmd
    
    #=====================================================
    if __name__ == '__main__':
        mqttc = mqtt.Client("test")
        mqttc.on_message = on_message
        mqttc.on_connect = on_connect
        mqttc.on_publish = on_publish
        mqttc.on_subscribe = on_subscribe
        mqttc.on_log = on_log
    
        # 设置账号密码(如果需要的话)
        #mqttc.username_pw_set(username, password=password)
    
        mqttc.connect(strBroker, port, 60)
        mqttc.subscribe(topic, 0)
        mqttc.loop_forever()

    server.py

    #!/usr/bin/python
    
    import sys
    import datetime
    import socket, sys
    import paho.mqtt.publish as publish
    
    def transmitMQTT(strMsg):
        strMqttBroker = "localhost"
        strMqttChannel = "test"
        print(strMsg)
        publish.single(strMqttChannel, strMsg, hostname = strMqttBroker)
    
    if __name__ == '__main__':
        transmitMQTT("Hello,MQTT")
        print "Send msg ok."

    四、开发中需要注意的一些问题

    • MQTT连接心跳时间

    • MQTT单个发布消息最大长度

    • 离线消息最长缓存时间

    • 单MQTT连接的最大订阅数

  • 相关阅读:
    自定义滚动条jQuery插件- Perfect Scrollbar
    js遍历for,forEach, for in,for of
    jQuery中$.extend(true,object1, object2);深拷贝对象
    使用遍历的方法实现对对象的深拷贝
    'NSUnknownKeyException' this class is not key value coding-compliant for the key XXX
    NSInternalInconsistencyException: loaded the "XXXView" nib but the view outlet was not set
    HTTP && socket
    stackview
    233. Number of Digit One *HARD* -- 从1到n的整数中数字1出现的次数
    231. Power of Two 342. Power of Four -- 判断是否为2、4的整数次幂
  • 原文地址:https://www.cnblogs.com/chenpingzhao/p/11383856.html
Copyright © 2011-2022 走看看