【问题标题】:How to run an infinite loop asynchronously in a websocket with Tornado如何使用 Tornado 在 websocket 中异步运行无限循环
【发布时间】:2018-02-19 07:56:47
【问题描述】:

我在一个记录温度等的树莓派上运行一个网络服务器。 我在 Tornado 中使用 websockets 与我的客户进行通信。 我希望客户端能够控制服务器何时通过套接字发送数据。

我的想法是,当客户端连接并说它已准备好时,服务器将启动一个循环,它每秒记录一次临时文件。但我需要这个循环异步运行。这就是我遇到麻烦的地方。我尝试按照示例进行操作,但无法正常运行。

class TemperatureSocketHandler(tornado.websocket.WebSocketHandler):

    @gen.coroutine
    def async_func(self):
        num = 0
        while(self.sending):
            num = num + 1
            temp = self.sense.get_temperature()
            yield self.write_message(str(temp))
            gen.sleep(1)

    def open(self):
        print("Temperature socket opened")
        self.sense = SenseHat()
        self.sense.clear()
        self.sending = False

    def on_message(self, message):
        if(message == "START"):
            self.sending = True
        if(message == "STOP"):
            self.sending = False

        tornado.ioloop.IOLoop.current().spawn_callback(self.async_func(self))

但是当我运行这个时我得到一个错误:

ERROR:tornado.application:Exception in callback functools.partial(<function wrap.<locals>.null_wrapper at 0x75159858>)
Traceback (most recent call last):
  File "/home/pi/.local/lib/python3.5/site-packages/tornado/ioloop.py", line 605, in _run_callback
    ret = callback()
  File "/home/pi/.local/lib/python3.5/site-packages/tornado/stack_context.py", line 277, in null_wrapper
    return fn(*args, **kwargs)
TypeError: 'Future' object is not callable

【问题讨论】:

  • 请修正缩进。你在on_message 中打电话给spawn_callback 吗?
  • 抱歉,已修复

标签: python asynchronous websocket webserver tornado


【解决方案1】:

你必须使用IOLoop.add_future() 因为async_func() 返回一个Future(它被装饰成协程!)。

此外,您应该在收到开始消息时添加未来,而不是在任何消息上:

def on_message(self, message):
        if(message == "START"):
            self.sending = True
            tornado.ioloop.IOLoop.current().add_future(
                self.async_func(self), lambda f: self.close())
        if(message == "STOP"):
            self.sending = False

【讨论】:

  • 文档说我需要两个参数来 add_future。第二个是回调。这个功能应该是什么?我对回调函数等不是很有经验。
  • 你是对的,当然。您必须指定回调。当 async_func() 返回时调用它(即 async_func 的 Future 有结果)。对于您的 WebSocket 处理程序,关闭套接字会很有用。或者,您可以向客户端发送“再见”消息(然后关闭套接字)。
猜你喜欢
  • 2023-04-05
  • 2021-11-13
  • 1970-01-01
  • 2015-05-25
  • 1970-01-01
  • 1970-01-01
  • 2020-05-11
  • 1970-01-01
  • 2018-07-29
相关资源
最近更新 更多