內(nèi)容原子官方文檔:
專注于為中小企業(yè)提供成都網(wǎng)站建設(shè)、做網(wǎng)站服務(wù),電腦端+手機(jī)端+微信端的三站合一,更高效的管理,為中小企業(yè)港口免費(fèi)做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動了上千家企業(yè)的穩(wěn)健成長,幫助中小企業(yè)通過網(wǎng)站建設(shè)實(shí)現(xiàn)規(guī)模擴(kuò)充和轉(zhuǎn)變。
Tornado基礎(chǔ)
Tornado是一套web框架和異步網(wǎng)絡(luò)功能庫,使用非阻塞式IO,可支持?jǐn)?shù)萬個(gè)活動連接。支持長活躍連接,支持 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.
●一個(gè)web框架,包含RequestHandler 用于創(chuàng)建web應(yīng)用程序。
●客戶端和服務(wù)端HTTP實(shí)現(xiàn)(HTTPServer and AsyncHTTPClient)。
●異步網(wǎng)絡(luò)庫(IOLoop and IOStream),可以用來建立HTTP組件,還可以實(shí)現(xiàn)其他協(xié)議。
●一個(gè)協(xié)程庫 (tornado.gen),可允許比鏈?zhǔn)交卣{(diào)地更加直接地編寫使用異步代碼。
Tornado可以作為WSGI容器,也可以被包含在其他WSGI容器。
的幾種異步接口:
Callback argument
Return a placeholder (Future, Promise, Deferred)
Deliver to a queue
Callback registry (e.g. POSIX signals)
●回調(diào)參數(shù)
●返回一個(gè)占位類 (Future, Promise, Deferred)
●遞交到隊(duì)列
●回調(diào)注冊(例如POSIX信號)
同步方式的代碼示例:
from tornado.httpclient import HTTPClientdef synchronous_fetch(url): http_client = HTTPClient() response = http_client.fetch(url) return response.body
回調(diào)方式的示例代碼:
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和協(xié)程方式的實(shí)例代碼:
from tornado import gen @gen.coroutine def fetch_coroutine(url): http_client = AsyncHTTPClient() response = yield http_client.fetch(url) raise gen.Return(response.body)
另一個(gè)gen和協(xié)程的實(shí)現(xiàn)代碼:
from tornado import gen@gen.coroutinedef fetch_coroutine(url): http_client = AsyncHTTPClient() response = yield http_client.fetch(url) return response.body
包含yield的函數(shù)是一個(gè)generator,它是異步的,返回generator對象無需等到運(yùn)行完成。
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)
協(xié)程調(diào)用模式
和回調(diào)交互:將調(diào)用包裹在Task中,可以返回一個(gè)Future對象,并加入回調(diào)的參數(shù)。
@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)
調(diào)用阻塞函數(shù):使用ThreadPoolExecutor,可以返回和協(xié)程兼容的Future。
thread_pool = ThreadPoolExecutor(4) @gen.coroutine def call_blocking(): yield thread_pool.submit(blocking_func, args)
并行執(zhí)行:協(xié)程裝飾器能識別類型為Futures的列表和字典,并且等待所有這些Future并行執(zhí)行完成
@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}
交替執(zhí)行:有些時(shí)候需要保存Future而不是讓他立即執(zhí)行,可以在等待時(shí)開始一個(gè)新的操作
@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()
循環(huán):需要從訪問的結(jié)果拆解循環(huán)條件,類似在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()
基本程序結(jié)構(gòu)
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('link to story 1' % 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或表單的數(shù)據(jù)
class MyFormHandler(RequestHandler): def get(self): self.write('') def post(self): self.set_header("Content-Type", "text/plain") self.write("You wrote " + self.get_body_argument("message"))
如果數(shù)據(jù)是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的錯(cuò)誤頁面。
on_connection_close - 客戶端斷開連接時(shí)調(diào)用; 應(yīng)用程序可以檢測這種情況 并終止后續(xù)的處理。 注意不能保證連接斷開的檢測是準(zhǔn)確的。
get_current_user - 參看 User authentication (用戶授權(quán))
get_user_locale - 返回 Locale 對象給當(dāng)前的用戶
set_default_headers - 可以用于設(shè)置附加的html相應(yīng)頭 (例如自定義Server 頭)
錯(cuò)誤處理
RequestHandler.write_error 用來產(chǎn)生一個(gè)錯(cuò)誤頁。
tornado.web.HTTPError用來產(chǎn)生錯(cuò)誤狀態(tài)碼。
重定向
可以通過兩種方式實(shí)現(xiàn)重定向。
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")), ])
支持正則表達(dá)式
app = tornado.web.Application([ url(r"/photos/(.*)", MyPhotoHandler), url(r"/pictures/(.*)", tornado.web.RedirectHandler, dict(url=r"/photos/\1")), ])
異步處理
異步處理通常可以使用兩種形式:
coroutine 裝飾器 + yield關(guān)鍵字
tornado.web.asynchronous裝飾器 + callback ,請求會一直保持打開,callback完成返回時(shí)調(diào)用RequestHandler.finish ,響應(yīng)這時(shí)再發(fā)出
callback模式的示例,使用內(nèi)置的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()
協(xié)程模式的示例:
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")