现在我正坐在一个项目上,其中python脚本订阅代理上的主题并等待消息。收到消息后,脚本会执行一些操作并显示图像大约5秒钟。到目前为止一切正常。
我正在努力解决的问题是,当函数已经执行时消息进入时,函数会在完成后再次直接执行。例如:如果3个消息一个接一个地直接发布,则该函数将一个接一个地调用,显示三次图像。
我想要实现的行为是忽略在函数执行时发布的消息。
此链接(http://www.steves-internet-guide.com/loop-python-mqtt-client/)表示:
当新消息到达Python MQTT客户端时,它们被放入 接收缓冲区。
消息位于此接收缓冲区中,等待被读取 客户计划。
我认为这就是问题所在!但我不明白如何避免这种缓冲行为。
喜欢建议我尝试使用设置标志等,但这不起作用。
为了更好地理解,我写了一个简单的脚本,在发布消息时打印1, 2, 3, 4, 5
#!/usr/bin/env python
import os, os.path
import time
import subprocess
import paho.mqtt.client as mqtt
mqtt_username = "user"
mqtt_password = "password"
mqtt_topic = "Topic"
def on_connect(client, userdata, flags, rc):
client.subscribe(mqtt_topic)
def on_message(client, userdata, msg):
print('1')
time.sleep(1)
print('2')
time.sleep(1)
print('3')
time.sleep(1)
print('4')
time.sleep(1)
print('5')
time.sleep(1)
print('---')
client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
client.username_pw_set(mqtt_username, mqtt_password)
client.connect("localhost", 1883, 60)
client.loop_forever()
使用此命令发布消息:
mosquitto_pub -d -u user -P password -t Topic -m "Hello"
发布一条消息一切都很好。直接一个接一个地发布三条消息会产生以下结果:
1
2
3
4
5
---
1
2
3
4
5
---
1
2
3
4
5
---
但它应该导致此输出,忽略其他两个消息:
1
2
3
4
5
---
答案 0 :(得分:0)
您可以拥有一个全局bool变量functionCalled
来保存函数是否被调用,另一个变量t
来保存time.time()
以记录调用函数的时间。也许你根据你的描述不需要一个变量来保持时间,但以防万一。
if functionCalled:
functionCalled = false
if Time.time() - t < 5 seconds:
# DontShowImage
else:
functionCalled = true
t = time.time()
# show image`
答案 1 :(得分:0)
该函数可以返回全局保存的时间戳。然后你可以在函数的第一行检查时间戳并立即返回,如果系统时间和那个时间戳之间的差异太小:
from datetime import datetime
lastMessage = 0
def on_message(client, userdata, msg):
if datetime.now().timestamp() - globals()['lastMessage'] > 5 # sec:
//this function shows an image for about 5 seconds
globals()['lastMessage'] = datetime.now().timestamp()