这是根据官方文档学习后总结的笔记:
Tornado基础
Tornado是一套web框架和异步网络功能库,使用非阻塞是IO,可支持数万个活动连接。支持长活跃连接,支持 long polling长连接,支持WebSockets。
A web framework (including RequestHandler which is subclassed to create web applications, and various supporting classes).
Client- and server-side implementions of HTTP (HTTPServer and AsyncHTTPClient).
An asynchronous networking library (IOLoop and IOStream), which serve as the building blocks for the HTTP components and can also be used to implement other protocols.
A coroutine library (tornado.gen) which allows asynchronous code to be written in a more straightforward way than chaining callbacks.
●一个web框架,包含RequestHandler 用于创建web应用程序。
●客户端和服务端HTTP实现(HTTPServer and AsyncHTTPClient)。
●异步网络库(IOLoop and IOStream),可以用来建立HTTP组件,还可以实现其他协议。
●一个协程库 (tornado.gen),可允许比链式回调地更加直接地编写使用异步代码。
Tornado可以作为WSGI容器,也可以被包含在其他WSGI容器。
的几种异步接口:
Callback argument
Return a placeholder (Future, Promise, Deferred)
Deliver to a queue
Callback registry (e.g. POSIX signals)
●回调参数
●返回一个占位类 (Future, Promise, Deferred)
●递交到队列
●回调注册(例如POSIX信号)
同步方式的代码示例:
from tornado.httpclient import HTTPClientdef synchronous_fetch(url): http_client = HTTPClient() response = http_client.fetch(url) return response.body
回调方式的示例代码:
from tornado.httpclient import AsyncHTTPClientdef asynchronous_fetch(url, callback): http_client = AsyncHTTPClient() def handle_response(response): callback(response.body) http_client.fetch(url, callback=handle_response)
使用Future的示例代码:
from tornado.concurrent import Futuredef async_fetch_future(url): http_client = AsyncHTTPClient() my_future = Future() fetch_future = http_client.fetch(url) fetch_future.add_done_callback( lambda f: my_future.set_result(f.result())) return my_future
使用gen和协程方式的实例代码:
from tornado import gen @gen.coroutine def fetch_coroutine(url): http_client = AsyncHTTPClient() response = yield http_client.fetch(url) raise gen.Return(response.body)
另一个gen和协程的实现代码:
from tornado import gen@gen.coroutinedef fetch_coroutine(url): http_client = AsyncHTTPClient() response = yield http_client.fetch(url) return response.body
包含yield的函数是一个generator,它是异步的,返回generator对象无需等到运行完成。
def run(self): # send(x) makes the current yield return x. # It returns when the next yield is reached future = self.gen.send(self.next) def callback(f): self.next = f.result() self.run() future.add_done_callback(callback)
协程调用模式
和回调交互:将调用包裹在Task中,可以返回一个Future对象,并加入回调的参数。
@gen.coroutinedef call_task(): # Note that there are no parens on some_function. # This will be translated by Task into # some_function(other_args, callback=callback) yield gen.Task(some_function, other_args)
调用阻塞函数:使用ThreadPoolExecutor,可以返回和协程兼容的Future。
thread_pool = ThreadPoolExecutor(4) @gen.coroutine def call_blocking(): yield thread_pool.submit(blocking_func, args)
并行执行:协程装饰器能识别类型为Futures的列表和字典,并且等待所有这些Future并行执行完成
@gen.coroutine def parallel_fetch(url1, url2): resp1, resp2 = yield [http_client.fetch(url1), http_client.fetch(url2)]@gen.coroutinedef parallel_fetch_many(urls): responses = yield [http_client.fetch(url) for url in urls] # responses is a list of HTTPResponses in the same order@gen.coroutinedef parallel_fetch_dict(urls): responses = yield {url: http_client.fetch(url) for url in urls} # responses is a dict {url: HTTPResponse}
交替执行:有些时候需要保存Future而不是让他立即执行,可以在等待时开始一个新的操作
@gen.coroutinedef get(self): fetch_future = self.fetch_next_chunk() while True: chunk = yield fetch_future if chunk is None: break self.write(chunk) fetch_future = self.fetch_next_chunk() yield self.flush()
循环:需要从访问的结果拆解循环条件,类似在Motor中的用法
import motordb = motor.MotorClient().test @gen.coroutine def loop_example(collection): cursor = db.collection.find() while (yield cursor.fetch_next): doc = cursor.next_object()
基本程序结构
from tornado.ioloop import IOLoop from tornado.web import RequestHandler, Application, url class HelloHandler(RequestHandler): def get(self): self.write("Hello, world")def make_app(): return Application([ url(r"/", HelloHandler), ]) def main(): app = make_app() app.listen(8888) IOLoop.current().start()
Application和路由
class MainHandler(RequestHandler): def get(self): self.write(‘<a href="%s">link to story 1</a>‘ % self.reverse_url("story", "1"))class StoryHandler(RequestHandler): def initialize(self, db): self.db = db def get(self, story_id): self.write("this is story %s" % story_id) app = Application([ url(r"/", MainHandler), url(r"/story/([0-9]+)", StoryHandler, dict(db=db), name="story") ])
本文出自 “LifeStage” 博客,请务必保留此出处http://soaop.blog.51cto.com/6164600/1610305
原文地址:http://soaop.blog.51cto.com/6164600/1610305