【问题标题】:How to run a looping function asynchronously in a Tornado.WebSocket class?如何在 Tornado.WebSocket 类中异步运行循环函数?
【发布时间】:2012-09-30 19:25:32
【问题描述】:

我正在使用 Tornado 运行 WebSocketHandler,并且我在 Handler 中有一个 while 循环。这个循环阻塞了一切——这很糟糕。如何使 tailstream() 函数异步(又名非阻塞)? (就像现在一样,tailstream 阻止了一切,甚至无法建立新的 websocket 连接。我需要它为每个 websocket 连接运行。)

(...)
class WSHandler(tornado.websocket.WebSocketHandler):
    connections = []
    filters = {}


    def allow_draft76(self):
        # for iOS 5.0 Safari
        return True


    def open(self):
        self.write_message('open')
        self.count = db.my_collection.count() - 1
        self.cursor = coll.find(tailable=True, await_data=True, skip=self.count)
        self.tailstream()




    def on_message(self, message):
        print message



    def on_close(self):
        self.connections.remove(self)
        self.cb.stop()
        print 'connection closed'


    @tornado.web.asynchronous
    def tailstream(self):
        while self.cursor.alive:
            try:
                doc = self.cursor.next()
                self.print2web(doc)

            except StopIteration:
                time.sleep(1)



    (...)       

【问题讨论】:

  • 我想我可以用threadingtailstream() 添加一个线程,但考虑到Tornado 有gen 引擎和所有这些,感觉有点脏?

标签: python asynchronous tornado


【解决方案1】:

我认为while 没有阻止它。但是time.sleep 做!

用这个answer 中的yield gen.Task(IOLoop.instance().add_timeout, time.time() + 5) 替换它。

如果它没有帮助 - 我们可以考虑整个解决方案的结构。

【讨论】:

  • 我会试试的。虽然while 循环永远运行 - 只是有时会进入睡眠状态。
  • 每个连接都永远运行?看起来你必须重新考虑建筑。它必须永远运行,但只有一个具有永远循环的实例必须存在。创建连接池并对其进行迭代。
  • 我会说有 10.000 个客户端连接到 WebSocketHandler - 我想每个都会产生自己的。我有大约 100 msg/second 来自可尾的 mongodb“流”,需要针对每个 WSH 进行不同的过滤并打印到客户端。像你提到的那样,我会更好地迭代一个与 mongodb 的“流”连接 - 或者 - 每个 WSH 都有自己的(异步)连接到 mongodb 吗?
  • 我需要运行一个这样的循环,但同时接受新的 WSH 连接。 (顺便说一句,阻止的不是time.sleep()。:)
  • 您确定尾流阻塞客户端吗?尝试仅使用print 语句运行它,而不进行其他操作。看看行为。
猜你喜欢
  • 1970-01-01
  • 2020-05-23
  • 1970-01-01
  • 2020-07-26
  • 2020-04-22
  • 2020-03-07
  • 1970-01-01
  • 2013-10-17
  • 2020-10-01
相关资源
最近更新 更多