简体   繁体   English

如何正确使用异步与龙卷风

[英]how to correctly use async with tornado

in the documents of tornado is mentioned that gen.coroutine decorators are from older versions.在 tornado 的文档中提到 gen.coroutine 装饰器来自旧版本。 newer should be used with aysnc.较新的应与 aysnc 一起使用。 So far a I failed to convert that little code for Tornado 6.0.3.到目前为止,我未能为 Tornado 6.0.3 转换那个小代码。

import tornado.web
import tornado.websocket
import tornado.httpserver

from random import randint
from tornado import gen
from tornado.ioloop import IOLoop

from web_handlers import HandlerIndexPage
from web_handlers import HandlerWebSocket

msg = 'none'

@gen.coroutine
def generate_random_int():
    global msg
    while True:
        msg = str(randint(0, 100))
        print('generated:', msg)
        yield gen.sleep(1.0)

@gen.coroutine
def generate_message_to_sockets():
    global msg
    while True:
        print ('new messageToCon: ', msg)
        yield [con.write_message(msg) for con in HandlerWebSocket.connections]
        yield gen.sleep(1.0)


class webApplication(tornado.web.Application):
    def __init__(self):
        handlers = [
            (r'/', HandlerIndexPage),
            (r'/websocket', HandlerWebSocket)
        ]

        settings = {
            'template_path': 'templates'
        }
        tornado.web.Application.__init__(self, handlers, **settings)

if __name__ == '__main__':
    ws_app = webApplication()
    server = tornado.httpserver.HTTPServer(ws_app)
    port = 9090
    server.listen(port)
    print('websocket listening on port:'+ str(port))
    IOLoop.current().spawn_callback(generate_random_int)
    IOLoop.current().spawn_callback(generate_message_to_sockets)
    IOLoop.instance().start()

How would I correctly use async?我将如何正确使用异步?

In Tornado, coroutines are generators that can be plugged into Python2 whereas async functions are first-class citizens in Python3.在 Tornado 中,协程是可以插入 Python2 的生成器,而异步函数是 Python3 中的一等公民。 They have different semantics (for instance, you can return from an async function, but not a coroutine).它们具有不同的语义(例如,您可以从异步 function return ,但不能从协程返回)。 The code you would need to change would look like:您需要更改的代码如下所示:

...

import asyncio

...

async def generate_random_int():
    global msg
    while True:
        msg = str(randint(0, 100))
        print('generated:', msg)
        await gen.sleep(1.0)

async def generate_message_to_sockets():
    global msg
    while True:
        print ('new messageToCon: ', msg)
        futures = [con.write_message(msg) for con in HandlerWebSocket.connections]
        if futures:
            await asyncio.wait(futures)
        await gen.sleep(1.0)
...

You can see an example similar to your use-case here:https://www.tornadoweb.org/en/stable/ioloop.html#ioloop-objects您可以在此处查看与您的用例类似的示例:https://www.tornadoweb.org/en/stable/ioloop.html#ioloop-objects

Python 3.5 introduced the async and await keywords (functions using these keywords are also called “native coroutines”). Python 3.5 引入了asyncawait关键字(使用这些关键字的函数也称为“本机协程”)。

# Decorated:                    # Native:

# Normal function declaration
# with decorator                # "async def" keywords
@gen.coroutine
def a():                        async def a():
    # "yield" all async funcs       # "await" all async funcs
    b = yield c()                   b = await c()
    # "return" and "yield"
    # cannot be mixed in
    # Python 2, so raise a
    # special exception.            # Return normally
    raise gen.Return(b)             return b

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM