in the documents of tornado is mentioned that gen.coroutine decorators are from older versions. newer should be used with aysnc. So far a I failed to convert that little code for 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. They have different semantics (for instance, you can return
from an async function, but not a coroutine). 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