tornado异步html
Tornado默认是单进程单线程。实时的web特性一般须要为每一个用户一个大部分时间都处于空闲的长链接. 在传统的同步web服务器中,这意味着须要给每一个用户分配一个专用的线程,这样的开销是十分巨大的。python
为了减少对于并发链接须要的开销,Tornado使用了一种单线程事件循环的方式. 这意味着全部应用程序代码都应该是异步和非阻塞的,由于在同一时刻只有一个操做是有效的。web
1 from tornado.web import Application, RequestHandler 2 from tornado.ioloop import IOLoop 3 from tornado.httpserver import HTTPServer 4 from tornado.httpclient import AsyncHTTPClient 5 from tornado.options import options, define 6 from tornado import gen 7 8 define('port', default=80, type=int) 9 10 11 12 class TestWebHandler(RequestHandler): 13 14 15 """网络请求阻塞""" 16 @gen.coroutine 17 def get(self): 18 client = AsyncHTTPClient() 19 url = 'https://vdn1.vzuu.com/SD/bea84ccc-a09e-11e9-bf0c-0a580a436135.mp4?disable_local_cache=1&bu=com&expiration=1563118410&auth_key=1563118410-0-0-84c3390428629c25b0179da9964f294c&f=mp4&v=hw' 20 res = yield client.fetch(url) 21 with open('2.mp4', 'wb+') as f: 22 f.write(res.body) 23 self.write("下载完成!") 24 25 class TestTimeHandler(RequestHandler): 26 27 """time sleep阻塞""" 28 @gen.coroutine 29 def get(self): 30 yield gen.sleep(5) 31 self.write("TestTimeHandler page") 32 33 34 class IndexHandle(RequestHandler): 35 def get(self): 36 self.write("index page") 37 38 app = Application( 39 handlers=[ 40 (r'/test', TestWebHandler), 41 (r'/time', TestTimeHandler), 42 (r'/', IndexHandle), 43 ] 44 ) 45 46 if __name__ == '__main__': 47 options.parse_command_line() 48 http = HTTPServer(app) 49 http.listen(options.port) 50 IOLoop.current().start()
当异步函数有返回值时,接受该异步方法的函数也应该异步执行,用yield接受返回值服务器
1 from tornado.web import Application, RequestHandler 2 from tornado.ioloop import IOLoop 3 from tornado.httpserver import HTTPServer 4 from tornado.options import options, define 5 from tornado import gen 6 7 define('port', default=80, type=int) 8 9 10 class Test: 11 12 @classmethod 13 @gen.coroutine 14 def get(self): 15 yield gen.sleep(1) 16 return "返回值" # python3.3以后能够直接使用return, 3.3之前使用raise gen.Return 17 18 19 class Index(RequestHandler): 20 # 接受异步方法返回值的方法也应该异步,而且使用yield接受参数 21 @gen.coroutine 22 def get(self): 23 resp = yield Test.get() 24 self.write(resp) 25 26 27 28 app = Application( 29 handlers=[ 30 31 (r'/', Index), 32 ] 33 ) 34 35 if __name__ == '__main__': 36 options.parse_command_line() 37 http = HTTPServer(app) 38 http.listen(options.port) 39 IOLoop.current().start()
tornado协程的三种方式网络
1 from tornado.web import RequestHandler, Application 2 from tornado.httpserver import HTTPServer 3 from tornado.ioloop import IOLoop 4 from tornado.options import options 5 from tornado import gen 6 7 8 class IndexHandle(RequestHandler): 9 @gen.coroutine 10 def get(self): 11 r1 = yield Index1Handle().get() 12 print(r1) 13 self.write(r1) 14 r2 = yield Index2Handle().get() 15 print(r2) 16 self.write(r2) 17 r3 = yield Index3Handle().get() 18 print(r3) 19 self.write(r3) 20 21 22 class Index2Handle: 23 @gen.coroutine 24 def get(self): 25 yield gen.sleep(5) 26 return "666" 27 28 29 class Index3Handle: 30 async def get(self): 31 await gen.sleep(5) 32 return "666" 33 34 35 class Index1Handle: 36 @gen.coroutine 37 def get(self): 38 yield gen.sleep(5) 39 raise gen.Return("666") 40 41 42 app = Application( 43 handlers=[ 44 (r'/', IndexHandle), 45 46 ] 47 ) 48 49 if __name__ == '__main__': 50 options.parse_command_line() 51 http = HTTPServer(app) 52 http.listen(80) 53 IOLoop.current().start()
tornado官方文档:https://www.osgeo.cn/tornado/gen.html#decorators并发