内容原子官方文档:
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") ])
处理输入请求
可以使用get_query_argument and get_body_argument方法,获取get或表单的数据
class MyFormHandler(RequestHandler): def get(self): self.write('<html><body><form action="/myform" method="POST">' '<input type="text" name="message">' '<input type="submit" value="Submit">' '</form></body></html>') def post(self): self.set_header("Content-Type", "text/plain") self.write("You wrote " + self.get_body_argument("message"))
如果数据是json方式的
def prepare(self): if self.request.headers["Content-Type"].startswith("application/json"): self.json_args = json.loads(self.request.body) else: self.json_args = None
write_error - 输出HTML的错误页面。
on_connection_close - 客户端断开连接时调用; 应用程序可以检测这种情况 并终止后续的处理。 注意不能保证连接断开的检测是准确的。
get_current_user - 参看 User authentication (用户授权)
get_user_locale - 返回 Locale 对象给当前的用户
set_default_headers - 可以用于设置附加的html相应头 (例如自定义Server 头)
错误处理
RequestHandler.write_error 用来产生一个错误页。
tornado.web.HTTPError用来产生错误状态码。
重定向
可以通过两种方式实现重定向。
RequestHandler.redirect and with theRedirectHandler.
RedirectHandler用于配置重定向在路由中。
app = tornado.web.Application([ url(r"/app", tornado.web.RedirectHandler, dict(url="http://itunes.apple.com/my-app-id")), ])
支持正则表达式
app = tornado.web.Application([ url(r"/photos/(.*)", MyPhotoHandler), url(r"/pictures/(.*)", tornado.web.RedirectHandler, dict(url=r"/photos/\1")), ])
异步处理
异步处理通常可以使用两种形式:
coroutine 装饰器 + yield关键字
tornado.web.asynchronous装饰器 + callback ,请求会一直保持打开,callback完成返回时调用RequestHandler.finish ,响应这时再发出
callback模式的示例,使用内置的AsyncHTTPClient:
class MainHandler(tornado.web.RequestHandler): @tornado.web.asynchronous def get(self): http = tornado.httpclient.AsyncHTTPClient() http.fetch("http://friendfeed-api.com/v2/feed/bret", callback=self.on_response) def on_response(self, response): if response.error: raise tornado.web.HTTPError(500) json = tornado.escape.json_decode(response.body) self.write("Fetched " + str(len(json["entries"])) + " entries " "from the FriendFeed API") self.finish()
协程模式的示例:
class MainHandler(tornado.web.RequestHandler): @tornado.gen.coroutine def get(self): http = tornado.httpclient.AsyncHTTPClient() response = yield http.fetch("http://friendfeed-api.com/v2/feed/bret") json = tornado.escape.json_decode(response.body) self.write("Fetched " + str(len(json["entries"])) + " entries " "from the FriendFeed API")
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。