首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在python线程中创建client.write_message

在python线程中创建client.write_message
EN

Stack Overflow用户
提问于 2022-08-13 13:22:19
回答 1查看 41关注 0票数 0

我目前正在制作一个websocket服务器,并使用python“旋风”来管理我家的家庭自动化。其原理如下:从网页用户发送命令(例如:打开浇水),服务器接收命令并激活连接到esp32的中继。

要创建浇水计划,我想我可以创建一个具有无限循环的线程,该线程可以查看数据库中保存的时间,做一个浇水时间减去当前时间的time.sleep,然后开始浇水。这部分很好,一切都很好。但是在那之后,我必须与连接的用户通信浇水是开着的,因此做一个client.write_message(‘浇水是打开’),但不幸的是龙卷风不允许它。那么,我怎样才能实现这样的目标呢?

在一些论坛上,人们建议使用一个接一个的命令来建立队列,这些命令一个接一个地被处理,有一个无限的while循环,但这不适合我,它阻止了我的程序。

提前谢谢你的回答。

代码语言:javascript
运行
复制
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.")

以上代码被简化为更简洁。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-08-17 19:50:52

我不认为你能从龙卷风的一条线上发送信息。您必须调用主线程来传递消息。

首先,将当前的IOLoop实例传递给wateringProgram函数。

使用IOLoop.add_callback从主线程发送消息。

下面是一个例子:

代码语言:javascript
运行
复制
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)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73344655

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档