MQTT 是一种基于 发布/订阅(publish/subscribe) 模式的“轻量级”通信协议,该协议创建在TCP/IP协议上。MQTT最大优势在于,能够以极少的代码和有限的宽带为远程链接设备提供实时可靠的消息服务。做为一种低开销、低宽带占用的即时通信协议,使其在物联网、小型设备、移动开发等方面有比较普遍的应用。 MQTT是一个基于客户端-服务器的消息发布/订阅传输协议,MQTT协议中有三种身份:发布者(Publish)、代理(Broker)(服务器)、订阅者(Subscribe),形式以下:
html
实现MQTT协议须要客户端和服务器端通信完成,在通信过程当中MQTT协议中有三种身份:发布者(Publish)、代理(Broker)(服务器)、订阅者(Subscribe)。其中消息的发布者和订阅者都是客户端,消息的代理是服务器,消息发布者能够同时是订阅者。 MQTT传输的消息分为:java
MQTT会构建镀层网络传输:他将创建客户端到服务器的链接,提供二者之间的一个有序的、无损的、基于字节流的双向传输。当应用数据经过MQTT网络发送时,MQTT会把与之相关的服务质量(Qos)和主题名(Topic)相关联。python
一个使用MQTT协议的应用程序或者设备,他老是创建到服务器的网络链接。客户端能够:bash
MQTT服务器以称为消息代理(Broker),能够是一个程序或一台设备他是位于消息发布者和订阅者之间,它能够:服务器
订阅包含主题筛选器(Topic Filter)和最大服务质量(Qos)。订阅会与一个会话(Session)关联。一个会话能够包含多个订阅。每一个会话中的每一个订阅都有一个不一样的主题筛选器。网络
每一个客户端与服务器创建链接后就是一个会话,客户端和服务器之间有状态交互。会话存在与一个网络之间,也可能在客户端和服务器之间跨越多个连续的网络链接。运维
链接到一个应用程序消息的标签,该标签与服务器的订阅相匹配。服务器会将消息发送给订阅者所匹配标签的每一个客户端。tcp
一个对主题名通配符筛选器,在订阅表达式中使用,表示订阅所匹配到的多个主题。函数
消息订阅者所具体接受的内容。oop
MQTT协议中定义了一些方法(也被称为动做),用于来表示对肯定资源所进行操做,这个资源能够表明预先存在的数据或动态生成数据,这取决于服务器的实现。一般来讲,资源指服务器上的文件或输出。主要方法有:
# 连接mqtt服务器函数
def on_mqtt_connect(self):
self.client.connect(self.MQTTHOST, self.MQTTPORT, 60)
# 开始监听
self.client.loop_start()
# 连接完成后的回调函数
def on_connect(self, client, userdata, flags, rc):
logging.info("+++ Connected with result code {} +++".format(str(rc)))
self.client.subscribe(self.topic_from_base)
复制代码
# 订阅函数
def subscribe(self):
self.client.subscribe(self.topic_from_base, 1)
# 消息到来处理函数
self.client.on_message = self.on_message
# 接收到信息后的回调函数, (client:客户端信息,userdata:用户信息,msg:消息体)
def on_message(self, client, userdata, msg):
pass
复制代码
# 数据发送函数
def publish(self, index, fuc):
# mqtt发送
self.client.publish(
self.topic_to_base, #主题
to_base_data # 消息题
)
复制代码
在MQTT协议中,一个MQTT数据包由:固定头(Fixed header)、可变头(Variable header)、消息题(Payload)三部分组成。MQTT数据包结构以下:
固定头存在与全部MQTT数据包中,使用两个字节看,共十六位 其结构以下:
位置:Byte 1中的4-7位。
使用四位二进制,可表明十六种类型消息:
除去0和15位置属于保留待用,共十四种消息时间类型。
位置:Byte 1 中的0-3
位置:Byte 2
固定头的第二字节用来保存变长头部和消息体的总大小的,但不是直接保存的。这一字节是能够扩展,其保存机制,前7位用于保存长度,后一部用作标识。当最后一位为1时,表示长度不足,须要使用二个字节继续保存。例如:计算出后面的大小为0
MQTT数据包中包含一个可变头,它驻位于固定的头和负载之间。不少类型数据包中都包括一个2字节的数据包标识字段,这些类型的包有:PUBLISH (QoS > 0)、PUBACK、PUBREC、PUBREL、PUBCOMP、SUBSCRIBE、SUBACK、UNSUBSCRIBE、UNSUBACK。可变头部内容字节长度 + Playload/负荷字节长度 = 剩余长度,这个是须要牢记的可变头的内容因数据包类型而不一样,较常的应用是做为包的标识:
Payload消息体位MQTT数据包的第三部分,包含CONNECT、SUBSCRIBE、SUBACK、UNSUBSCRIBE四种类型的消息:
python 简单测试代码
# -*- coding: utf-8 -*-
import paho.mqtt.client as mqtt
import time
class Mqtt(object):
def __init__(self):
self.MQTTHOST = "********"
self.MOTTPORT = "********"
self.client_id = time.strftime('%Y%m%d%H%M%S',time.localtime(time.time()))
self.client = mqtt.Client(self.client_id)
self.client.username_pw_set()
# 设置连接上服务器后回调函数
self.client.on_connect = self.on_connect
# 设置接收到服务器消息后回调函数
self.client.on_message = self.on_message
# 链接服务器,维持心跳为60秒
self.client.connect(self.MQTTHOST, self.MOTTPORT, 60)
self.client.loop_forever()
def on_connect(self,client, userdata, flag, rc):
print("Connected with result code " + str(rc))
client.subscribe("test")
def on_publish(self, topic, payload, qos):
self.client.publish(topic, payload, qos)
print(topic+"消息发送成功。。。。。")
return 1
def on_message(self, client, userdata, msg):
print(msg.topic+ "" +msg.payload.decode("utf-8"))
return 1
def on_subscribe(self, topic):
self.client.subscribe(topic, 1)
self.client.on_message = self.on_message
return 1
if __name__ == "__main__":
mqtt = Mqtt()
mqtt.on_publish("test", "helloWord",1)
复制代码
https://www.jianshu.com/p/5c42cb0ed1e9
http://www.runoob.com/w3cnote/mqtt-intro.html
http://www.blogjava.net/yongboy/archive/2014/02/07/409587.html
新手上车,请多指教,若有问题,请邮件联系:young5678@qq.com