【问题标题】:Tornado Chatdemo to work with CoroutinesTornado Chatdemo 与协程一起工作
【发布时间】:2014-06-19 17:17:30
【问题描述】:

我正在尝试制作 tornado 聊天演示的协程版本,但我无法理解它。因为我是协程编程风格的新手,我真的很讨厌自 javascript 以来的回调。

我想将 MessageUpdateHandler 更改为真正使用协程。

class MessageBuffer(object):
    def __init__(self):
        self.waiters = set()
        self.cache = []
        self.cache_size = 200

    def wait_for_messages(self, callback, cursor=None):
        if cursor:
            new_count = 0
            for msg in reversed(self.cache):
                if msg["id"] == cursor:
                    break
                new_count += 1
            if new_count:
                callback(self.cache[-new_count:])
                return
        self.waiters.add(callback)

    def cancel_wait(self, callback):
        self.waiters.remove(callback)

    def new_messages(self, messages):
        logging.info("Sending new message to %r listeners", len(self.waiters))
        for callback in self.waiters:
            try:
                callback(messages)
            except:
                logging.error("Error in waiter callback", exc_info=True)
        self.waiters = set()
        self.cache.extend(messages)
        if len(self.cache) > self.cache_size:
            self.cache = self.cache[-self.cache_size:]


# Making this a non-singleton is left as an exercise for the reader.
global_message_buffer = MessageBuffer()


class MessageUpdatesHandler(BaseHandler):
    @tornado.web.authenticated
    @tornado.web.asynchronous
    def post(self):
        cursor = self.get_argument("cursor", None)
        global_message_buffer.wait_for_messages(self.on_new_messages,
                                                cursor=cursor)

    def on_new_messages(self, messages):
        # Closed client connection
        if self.request.connection.stream.closed():
            return
        self.finish(dict(messages=messages))

    def on_connection_close(self):
        global_message_buffer.cancel_wait(self.on_new_messages)

我尝试删除 @tornado.web.asynchronous 并替换为 @tornado.gen.coroutine 但这就是我所能做到的,我不明白如何在没有 on_new_messages(self, messages) 回调的情况下产生 global_message_buffer.wait_for_messages(),据我所知,它会使回调过时。 global_message_buffer 设计有回调,但是,yields 没有回调,那么如何让它们产生呢?

tornado 聊天示例演示:https://github.com/tornadoweb/tornado/blob/c9af9a7224b1f42e91ad88b0a3f8f10478584b0a/demos/chat/chatdemo.py#L101

【问题讨论】:

    标签: python asynchronous web tornado coroutine


    【解决方案1】:

    这是一个简单的例子,希望对你有帮助:

    class MessageUpdatesHandler(BaseHandler):
        @tornado.web.authenticated
        @gen.coroutine
        def post(self):
            cursor = self.get_argument("cursor", None)
            messages = yield gen.Task(global_message_buffer.wait_for_messages, cursor=cursor)
    
            if self.request.connection.stream.closed():
                return
    
            self.finish(dict(messages=messages))
    

    【讨论】:

    • global_message_buffer 需要回调,我已经添加了问题
    • 方法“gen.Task”会传递一个回调参数给“global_message_buffer.wait_for_messages”,你可以先试试。
    • 谢谢我今天会测试。看起来很有希望。Torndado 开发人员说它的工作在 cancel_wait 时很尴尬。我得去看看。
    猜你喜欢
    • 2016-08-28
    • 1970-01-01
    • 2015-08-06
    • 1970-01-01
    • 2021-10-28
    • 2017-03-28
    • 1970-01-01
    • 2018-11-21
    • 1970-01-01
    相关资源
    最近更新 更多