如何通过mqtt实现一个"mailbox"服务?

How to implement a "mailbox" service through mqtt?

我是所有 mqtt 的新手,作为第一个练习,我想通过持久的 mqtt 会话创建一个“邮箱”服务。奖励是一个低功耗 ESP8266 设备,它大部分时间都处于睡眠状态,并定期唤醒并检查是否有任何待处理的命令。

我尝试通过我的 Linux 主机上的发送者和接收者使用 python 和 paho mqtt 来实现这一点。 Mosquitto 作为经纪人在后台 运行。

这里首先是“mbox”发件人,每次按下 Enter 时它都会发送另一条消息。

import paho.mqtt.client as mqtt 

broker_address='127.0.0.1'
client = mqtt.Client('MBoxClient') 
client.connect(broker_address)

counter = 1
while True:
  print('Press Enter to send msg #'+str(counter)+': ', end='')
  if input().startswith('q'):
    break
  client.publish("mbox/mail","Hello "+str(counter), qos=1)
  counter += 1
client.disconnect()
print('done!')

这是我的 mbox 接收器:

import paho.mqtt.client as mqtt
import time

def on_message(client, userdata, message):
  print("message:", message.topic + ': ' + str(message.payload.decode("utf-8")))

print('I\'m listening for mbox messages!')
broker_address="127.0.0.1"
client_name='mbox'
is_first=True
while 1:
  client = mqtt.Client(client_name, clean_session=is_first)
  is_first=False
  print("polling")
  client.on_message=on_message 
  client.connect(broker_address) 
  client.subscribe('mbox/#',qos=1)
  client.loop_start()
  time.sleep(0.1) # How long should this time be?
  client.loop_stop()
#  client.loop(0.1) # why doesn't this do the same action as the previous three lines?
  client.disconnect()
  time.sleep(5)

尽管这可行,但我觉得我的解决方案非常老套。 client.loop_start()client.loop_stop() 创建另一个线程。但是当我尝试做 client.loop(0.1) 而不是它时。

所以我的问题是:

问题按顺序回答。

  • 不,轮询完全违背了像 MQTT
  • 这样的 pub/sub 协议的意义
  • 你真的应该在循环中调用 client.loop(),它默认只在提供的超时期限内处理 1 个数据包。 QOS1需要多个数据包才能完成投递。
  • 调用 client.loop(0.1) 将阻塞 0.1 秒等待传入消息,然后 return。如果消息在 0.1 秒后到达,它将位于 OS TCP/IP 堆栈中,直到您再次调用 client.loop()。如果您没有定期调用它,那么代理将启动客户端,因为 KeepAlive 测试将失败。客户端循环还处理发送所有订阅消息。
  • 假设消息在 QOS > 0 发布并且您在 QOS > 0 订阅并且客户端 ID 保持不变并且干净的会话为 false 经纪人应该交付并且订阅者离线时发布的消息
  • 如前所述,您需要为每条消息多次调用 client.loop(),因为每个唤醒周期您只调用一次。启动后台线程将在您设置的时间长度内处理所有必需的消息 运行 for.