# -*- coding: utf-8 -*- """ @author: Mr_zhang @software: PyCharm @file: publish.py @time: 2022/5/7 21:30 """ import json import time from paho.mqtt import client as mqtt_client class Publish: """消息發佈者""" message = None def __init__(self, client_id, host, port, keepalive=60): self.client_id = client_id self.host = host self.port = port self.keepalive = keepalive self.username = "admin" self.password = "admin" @staticmethod def on_connect(client, userdata, flags, rc): """當代理響應連接請求時調用""" print("on_connect: ", client, rc) @staticmethod def on_disconnect(client, userdata, rc): """當與代理斷開連接時調用""" print("on_disconnect: ", client, rc) def on_message(self, client, userdata, message): """當收到關於客戶訂閱的主題的消息時調用""" print("on_message: ", client, message) _message = json.loads(message.payload.decode()) self.message = _message client.disconnect() @staticmethod def on_publish(client, userdata, mid): """當使用使用publish()發送的消息已經傳輸到代理時被調用""" print("on_publish: ", client, userdata, mid) @staticmethod def on_subscribe(client, userdata, mid, granted_qos): """當代理響應訂閱請求時被調用""" print("on_subscribe: ", client) @staticmethod def on_unsubscribe(client, userdata, mid): """當代理響應取消訂閱請求時調用""" print("on_unsubscribe: ", client) @staticmethod def on_log(client, userdata, level, buf): """當客戶端有日誌信息時調用""" print("on_log: ", client) def connect_mqtt(self): """連接mqtt服務器""" client = mqtt_client.Client( self.client_id, protocol=mqtt_client.MQTTv311, transport="tcp" ) client.username_pw_set(self.username, self.password) client.on_connect = self.on_connect client.on_disconnect = self.on_disconnect client.on_message = self.on_message client.on_publish = self.on_publish client.on_subscribe = self.on_subscribe client.on_unsubscribe = self.on_unsubscribe # client.on_log = self.on_log client.connect(host=self.host, port=self.port, keepalive=self.keepalive) return client @staticmethod def publish(client, topic, message): """發佈消息""" result = client.publish(topic, payload=json.dumps(message), qos=1) status = result[0] if status == 0: print(f"send {message} to {topic}") else: client.loop_stop() print(f"failed to send message to {topic}") def send(self, topic, message, callback=True): """ 主程序運行 :param topic: 訂閱主題 :param message: 消息 :param callback: 是否需要返回值,默認需要 :return: """ client = self.connect_mqtt() self.publish(client=client, topic=topic, message=message) if callback: client.subscribe(self.client_id) client.loop_forever() else: client.loop_start() if __name__ == "__main__": _client_id = "mqtt-tcp-pub-{id}".format(id=time.time() * 100000) data = {"client_id": _client_id, "data": {"k": "v"}, "callback": True} # pub = Publish(client_id=_client_id, host="127.0.0.1", port=1883, keepalive=60) # pub.send(topic="TEST", message=data, callback=True) # print(pub.message)
# -*- coding: utf-8 -*- """ @author: Mr_zhang @software: PyCharm @file: subscribe.py @time: 2022/5/7 21:30 """ import json import time from paho.mqtt import client as mqtt_client class Subscribe: """消息訂閱者""" def __init__(self, client_id, host, port, keepalive=60): self.client_id = client_id self.host = host self.port = port self.keepalive = keepalive self.topic = None self.username = "admin" self.password = "admin" @staticmethod def on_connect(client, userdata, flags, rc): """當代理響應連接請求時調用""" print("on_connect: ", client, rc) @staticmethod def on_disconnect(client, userdata, rc): """當與代理斷開連接時調用""" print("on_disconnect: ", client, rc) @staticmethod def on_message(client, userdata, message): """當收到關於客戶訂閱的主題的消息時調用""" print("on_message: ", client) _message = json.loads(message.payload.decode()) callback = _message.get("callback") print(_message) data = _message.get("data") # 這裏執行單獨業務邏輯,如果是HTTP請求,建議設置超時時間 if callback: # 是否需要返回值 client_id = _message.get("client_id") client.publish( client_id, payload=json.dumps({"client_id": client_id, "message": "自定義消息體返回."}), qos=1, ) @staticmethod def on_publish(client, userdata, mid): """當使用使用publish()發送的消息已經傳輸到代理時被調用""" print("on_publish: ", client, userdata, mid) @staticmethod def on_subscribe(client, userdata, mid, granted_qos): """當代理響應訂閱請求時被調用""" print("on_subscribe: ", client) @staticmethod def on_unsubscribe(client, userdata, mid): """當代理響應取消訂閱請求時調用""" print("on_unsubscribe: ", client) @staticmethod def on_log(client, userdata, level, buf): """當客戶端有日誌信息時調用""" print("on_log: ", client) def connect_mqtt(self): """連接mqtt服務器""" client = mqtt_client.Client( self.client_id, protocol=mqtt_client.MQTTv311, transport="tcp" ) client.username_pw_set(self.username, self.password) client.on_connect = self.on_connect client.on_disconnect = self.on_disconnect client.on_message = self.on_message client.on_publish = self.on_publish client.on_subscribe = self.on_subscribe client.on_unsubscribe = self.on_unsubscribe # client.on_log = self.on_log client.connect(host=self.host, port=self.port, keepalive=self.keepalive) return client @staticmethod def subscribe(client, topic): """發佈消息""" client.subscribe(topic, qos=1) def receive(self, topic): """主程序運行""" self.topic = topic client = self.connect_mqtt() self.subscribe(client, topic) client.loop_forever() if __name__ == "__main__": _client_id = "mqtt-tcp-sub-{id}".format(id=time.time() * 100000) # pub = Subscribe( # client_id=_client_id, host="127.0.0.1", port=1883, keepalive=60 # ) # pub.receive(topic="TEST")
生產者跟消費者的角色有時候可以互相轉換。生產者亦可作爲消費者。
mqtt模擬HTTP請求。可獲取狀態碼信息