如何使用 Tornado 在 websocket 中异步 运行 无限循环

How to run an infinite loop asynchronously in a websocket with Tornado

我正在 运行 在 raspberry pi 上安装一个 Web 服务器,它正在记录温度等。 我在 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

你必须使用 IOLoop.add_future() 因为 async_func() returns a 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