如何正确使用龙卷风异步
how to correctly use async with tornado
在 tornado 的文档中提到 gen.coroutine 装饰器来自旧版本。较新的应该与aysnc一起使用。到目前为止,我未能为 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()
如何正确使用异步?
在 Tornado 中,协程是可以插入 Python2 的生成器,而异步函数是 Python3 中的第一个 class 公民。它们具有不同的语义(例如,您可以从异步函数 return
而不是协程)。您需要更改的代码如下所示:
...
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)
...
您可以在此处查看与您的用例类似的示例:https://www.tornadoweb.org/en/stable/ioloop.html#ioloop-objects
Python 3.5引入了async
和await
关键字(使用这些关键字的函数也称为“原生协程”)。
# 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
在 tornado 的文档中提到 gen.coroutine 装饰器来自旧版本。较新的应该与aysnc一起使用。到目前为止,我未能为 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()
如何正确使用异步?
在 Tornado 中,协程是可以插入 Python2 的生成器,而异步函数是 Python3 中的第一个 class 公民。它们具有不同的语义(例如,您可以从异步函数 return
而不是协程)。您需要更改的代码如下所示:
...
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)
...
您可以在此处查看与您的用例类似的示例:https://www.tornadoweb.org/en/stable/ioloop.html#ioloop-objects
Python 3.5引入了async
和await
关键字(使用这些关键字的函数也称为“原生协程”)。
# 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