守护 Python 脚本实现 Paho

问题描述

我有一个 Python 脚本,它实现了 Paho 库以订阅和重新发布来自 Mosquitto 服务器的 MQTT 主题。当我从终端调用它时,我的脚本工作正常。什么让我绊倒是试图守护脚本运行无人看管。我正在使用 daemonize 库,虽然我可以让脚本作为守护程序启动,但它实际上没有任何事情。当我运行非守护程序脚本时,我看到在我指定的端点收到了 MQTT 消息,但是当相同的脚本作为守护程序运行时,我的接收端点没有显示任何消息。我包括了非守护程序和守护程序脚本以供参考。

关于为什么非守护脚本有效而守护脚本不起作用的任何想法?

非守护进程

import paho.mqtt.client as mqtt
import random
import json
import time

#replace [device-id] with your device you created in IoT Hub.
iothubmqtttopic = "devices/MoxieSensorsBHM/messages/events/"

#define on_connect function
def on_connect(client,userdata,flags,rc):
        print("Connected with result code " + str(rc))
        client.subscribe("MW/oneal/Tag/#")

#define on_message function - this function translates the incoming topic
#and publishes to the specified topic for IoT Hub
def on_message(client,message):
        global iothubmqtttopic
        topic = message.topic
        if(topic != iothubmqtttopic):

                #extract the sensor ID from the topic
                splitTopic = topic.split("/") #split the topic into a list
                sensorID = splitTopic[3] #the 3rd item in the list is the sensor ID
                msgType = splitTopic[4] #the 4th item in the list is the type (e.g. status,UWB)

                #convert the json response to a python dictionary object
                m_decode = str(message.payload.decode("utf-8"))
                m_in = json.loads(m_decode)

                #get current time for timestamp
                ts = time.gmtime()
                tsFormatted = time.strftime("%Y-%m-%d %H:%M:%s",ts)

                #add new elements to the dictionary for topic and sensor ID
                m_in["topic"] = topic
                m_in["sensorID"] = sensorID
                m_in["messageType"] = msgType
                m_in["timestamp"] = tsFormatted

                #set the propertybag for IoT Hub
                propertybag = "topic=" + topic + "&sensorID=" + sensorID + "&messageType=" + msgType
                print(propertybag)

                #convert back to JSON
                m_encode = json.dumps(m_in)

                #create an array of all the possible sensor IDs

                #print to screen and publish to IoT Hub
                print("Topic: ",topic)
                print("Message received: ",m_encode)
                print("IoT Hub Topic: ",iothubmqtttopic)
                client.publish(iothubmqtttopic,m_encode)

# replace <broker address> with the FQDN or IP address of your MQTT broker
broker_address="localhost"

#create the client and connect to the broker
print("creating new instance")
client = mqtt.Client("iottopicxlate" + str(random.randrange(1,1000000))) #create new instance
client.on_message=on_message #attach function to callback
print("connecting to broker")
client.connect(broker_address) #connect to broker
client.on_connect = on_connect #attach function to callback

client.loop_forever() #stop the loop

守护进程

import paho.mqtt.client as mqtt
import random
import json
import time
import os,sys
from daemonize  import Daemonize

def main():
        #replace [device-id] with your device you created in IoT Hub.
        iothubmqtttopic = "devices/MoxieSensorsBHM/messages/events/"

        #define on_connect function
        def on_connect(client,rc):
                #print("Connected with result code " + str(rc))
                client.subscribe("MW/oneal/Tag/#")

        #define on_message function - this function translates the incoming topic
        #and publishes to the specified topic for IoT Hub
        def on_message(client,message):
                global iothubmqtttopic
                topic = message.topic
                if(topic != iothubmqtttopic):

                        #extract the sensor ID from the topic
                        splitTopic = topic.split("/") #split the topic into a list
                        sensorID = splitTopic[3] #the 3rd item in the list is the sensor ID
                        msgType = splitTopic[4] #the 4th item in the list is the type (e.g. status,UWB)

                        #convert the json response to a python dictionary object
                        m_decode = str(message.payload.decode("utf-8"))
                        m_in = json.loads(m_decode)

                        #get current time for timestamp
                        ts = time.gmtime()
                        tsFormatted = time.strftime("%Y-%m-%d %H:%M:%s",ts)

                        #add new elements to the dictionary for topic and sensor ID
                        m_in["topic"] = topic
                        m_in["sensorID"] = sensorID
                        m_in["messageType"] = msgType
                        m_in["timestamp"] = tsFormatted

                        #set the propertybag for IoT Hub
                        propertybag = "topic="+topic+"&sensorID="+sensorID+"&messageType="+msgType
                        #print(propertybag)

                        #convert back to JSON
                        m_encode = json.dumps(m_in)

                        #print to screen and publish to IoT Hub
                        print("Topic: ",topic + propertybag)
                        print("Message received: ",m_encode)
                        client.publish(iothubmqtttopic,m_encode)

        # replace <broker address> with the FQDN or IP address of your MQTT broker
        broker_address="localhost"

        #create the client and connect to the broker
        #print("creating new instance")
        client = mqtt.Client("iottopicxlate" + str(random.randrange(1,1000000))) #create new instance
        client.on_message=on_message #attach function to callback
        #print("connecting to broker")
        client.connect(broker_address) #connect to broker
        client.on_connect = on_connect #attach function to callback

        client.loop_forever() #stop the loop

#start the daemon
topictransdpid = os.path.basename(sys.argv[0])
pidfile = "topictransd.pid"
daemon = Daemonize(app = "topictransd",pid = pidfile,action = main)
daemon.start()

更新 文森特,我正在尝试执行您的建议以写入文件进行调试。请耐心等待,因为我正在快速学习 Python。我已将以下代码片段添加到脚本的非守护程序(即工作)版本中的 on_message 函数中,并且我看到了写入“调试”目录中文文件的消息。当我在守护程序版本中实现相同的片段时,没有写入任何文件。所以当我的守护进程运行时,它实际上并没有做任何事情。

                f = open("debug/" + sensorID+tsFormatted + ".txt","x")
                f.write(m_encode)
                f.close

对我遗漏的东西有什么想法吗?

更新 2 我实现了一个简单的记录器,用于在脚本启动时编写调试消息,并在 daemonize 调用 main() 函数时编写另一个记录器。我的日志文件一个启动脚本的条目,但是没有一个条目用于调用 main() 时 - 好像 daemonize 没有执行 main() 函数?这是我启用了记录器的更新后的守护程序脚本:

import paho.mqtt.client as mqtt
import random
import json
import time
import logging
import os,sys
from daemonize  import Daemonize

def main():
        logger.warning("main has been started") # write a log file entry to indicate main has been called by daemonize
        #replace [device-id] with your device you created in IoT Hub.
        iothubmqtttopic = "devices/MoxieSensorsBHM/messages/events/"

        #define on_connect function
        def on_connect(client,ts)

                        #add new elements to the dictionary for topic and sensor ID
                        m_in["topic"] = topic
                        m_in["sensorID"] = sensorID
                        m_in["messageType"] = msgType
                        m_in["timestamp"] = tsFormatted

                        #set the propertybag for IoT Hub
                        propertybag = "topic="+topic+"&sensorID="+sensorID+"&messageType="+msgType
                        #print(propertybag)

                        #convert back to JSON
                        m_encode = json.dumps(m_in)

                        #print to screen and publish to IoT Hub
                        #print("Topic: ",topic + propertybag)
                        #print("Message received: ",m_encode)

                        #write the message to a debug file
                        f = open("debug/" + sensorID+tsFormatted + ".txt","w")
                        f.write(m_encode)
                        f.close

        # replace <broker address> with the FQDN or IP address of your MQTT broker
        broker_address="localhost"

        #create the client and connect to the broker
        #print("creating new instance")
        client = mqtt.Client("iottopicxlate" + str(random.randrange(1,1000000))) #create new instance

        #create a logger
        #logging.basicConfig(level=logging.DEBUG,filename="topictransd.log",format="%(asctime)s %(message)s",filemode="w")
        #logger = logging.getLogger()
        #client.enable_logger(logger)

        client.on_message=on_message #attach function to callback
        #print("connecting to broker")
        client.connect(broker_address) #connect to broker
        client.on_connect = on_connect #attach function to callback

        #start the loop
        client.loop_forever()

#start the daemon
logging.basicConfig(level=logging.DEBUG,filemode="w")
logger = logging.getLogger()

pidfile = "topictransd.pid"
logger.warning("successfully started the script") # write a log file entry to indicate the script has successfully started
daemon = Daemonize(app = "topictransd",action = main)
daemon.start()

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)