我目前正在制作一个websocket服务器,并使用python“旋风”来管理我家的家庭自动化。其原理如下:从网页用户发送命令(例如:打开浇水),服务器接收命令并激活连接到esp32的中继。
要创建浇水计划,我想我可以创建一个具有无限循环的线程,该线程可以查看数据库中保存的时间,做一个浇水时间减去当前时间的time.sleep,然后开始浇水。这部分很好,一切都很好。但是在那之后,我必须与连接的用户通信浇水是开着的,因此做一个client.write_message(‘浇水是打开’),但不幸的是龙卷风不允许它。那么,我怎样才能实现这样的目标呢?
在一些论坛上,人们建议使用一个接一个的命令来建立队列,这些命令一个接一个地被处理,有一个无限的while循环,但这不适合我,它阻止了我的程序。
提前谢谢你的回答。
class WSHandler(tornado.websocket.WebSocketHandler):
def wateringProgram():
time.sleep(secondsBeforeOnWatering) # secondsBeforeOnWatering in a db
watering.on()
for client in clients:
client.write_message('watering is on')
time.sleep(wateringDuration) # wateringDuration in a db
watering.off()
for client in clients:
client.write_message('watering is off')
threadProgram = threading.Thread(target=wateringProgram, args=())
threadProgram.start()
def open(self):
WSHandler.clients.add(self)
self.write_message('logs')
print ('[SERVEUR] Connection was opened')
def on_message(self, message):
if message == 'program changing':
threadProgram.restart() # restart with the new timing
def on_close(self):
WSHandler.clients.remove(self)
print ('[WS] Connection was closed.')
application = tornado.web.Application([
(r'/ws', WSHandler),
], **settings)
if __name__ == "__main__":
try:
http_server = tornado.httpserver.HTTPServer(application)
http_server.listen(PORT)
main_loop = tornado.ioloop.IOLoop.instance()
print ("Tornado Server started")
main_loop.start()
except:
print ("Exception triggered - Tornado Server stopped.")以上代码被简化为更简洁。
发布于 2022-08-17 19:50:52
我不认为你能从龙卷风的一条线上发送信息。您必须调用主线程来传递消息。
首先,将当前的IOLoop实例传递给wateringProgram函数。
使用IOLoop.add_callback从主线程发送消息。
下面是一个例子:
class WSHandler(tornado.websocket.WebSocketHandler):
def wateringProgram(loop):
time.sleep(secondsBeforeOnWatering) # secondsBeforeOnWatering in a db
watering.on()
loop.add_callback(WSHandler.send_message_to_all, msg='watering is on')
time.sleep(wateringDuration) # wateringDuration in a db
watering.off()
loop.add_callback(WSHandler.send_message_to_all, msg='watering is on')
threadProgram = threading.Thread(target=wateringProgram, args=(tornado.ioloop.IOLoop.current(),))
threadProgram.start()
@classmethod
def send_message_to_all(cls, msg):
for client in cls.clients:
client.write_message(msg)https://stackoverflow.com/questions/73344655
复制相似问题