初學Tornado框架以及和Django的對比
django和tornado區別
* 效能
* 多執行緒或者多程序
* django使用的是( 多執行緒或者多程序)
* tornado使用的是協程(微執行緒),協程效能非常高(沒有執行緒這種上下文建立,切換的開銷)yield
* 功能
* django 大而全(什麼都有)(定製太困難了)
後臺(admin)
orm(物件關係對映類庫)
session
* tornado 小而精 (輕量級)什麼也沒有
* tornado 單執行緒非同步分阻塞(node.js)
* tornado適用場景
高併發,長連線
### tornado單執行緒非同步分阻塞 ###
* 程式碼
# 處理網路請求的
class IndexHandler(tornado.web.RequestHandler):
# get請求
def get(self):
# 輸出響應體
self.write('hello world')
#Application 其實是一個設定的容器
app = tornado.web.Application([
(r'/',IndexHandler)
])
# 繫結埠(呼叫了HttpServer)
app.listen(8000)
# 死迴圈(從epoll中獲得需要操作的socket)
tornado.ioloop.IOLoop.instance().start()
* epoll
* 客戶端socket的儲存的容器
### 步驟 ###
* 清理類(RequestHandler)
* Application物件 (很多設定)
* app.listen(8000) 繫結埠,建立伺服器
* ioLoop.start(不斷的從epoll中讀取要處理的客戶端socket)
### 為什麼tornado能處理高併發,長連線 ###
* 長連線(epoll容器儲存起來了)
* 高併發(使用的是協程,沒有執行緒建立和執行緒上下文切換開銷)
def printa():
while True:
yield 'a'
def printb():
while True:
yield 'b'
while True:
pirnta()
printb()
abababababab
### tornado特性 ###
* 單執行緒
* 非同步(協程)
* 非阻塞
### 查詢引數 ###
* get/post
* get get_query_argument get_query_arguments
* post get_body_argument get_body_arguments
* 縮寫 get_argument get_arguments(通用的)
* 捕獲
class TimeHandler(tornado.web.RequestHandler): def get(self,year,month,day): self.write('time'+year+month+day) app = tornado.web.Application([ (r'/time/(?P<month>\d+)/(?P<year>\d+)/(?P<day>\d+)',TimeHandler),具名捕獲 (r'/time/(\d+)/(\d+)/(\d+)',TimeHandler), ]) * self.write(響應體) * file,大檔案
### 查詢I(Input) ###
* get_argument 獲得get/post引數
* 捕獲/具名捕獲
* self.request.files 上傳多個檔案
* self.request.headers 請求頭
* self.request.remote_ip 獲得客戶端ip
class FileHandler(tornado.web.RequestHandler): def get(self, *args, **kwargs): if 'img' in self.request.files: imgfile=self.request.files['img'] filename=imgfile[0]['filename'] filebody=imgfile[0]['body'] if not os.path.exists(MEDIA_ROOT): os.makedirs(MEDIA_ROOT) with open(os.path.join(MEDIA_ROOT,filename),'wb') as fw: fw.write(filebody) self.write('上傳成功')
class IPBlock(object): def __init__(self,get_response): self.get_response = get_response def __call__(self, handler=None,*args, **kwargs): BLACK_IP=['127.0.0.1'] if handler.request.remote_ip in BLACK_IP: handler.write('禁止訪問') return return self.get_response(handler) class RemoteIPHandler(tornado.web.RequestHandler): # @IPBlock def get(self, *args, **kwargs): self.write(u'您的ip是:'+self.request.remote_ip) #get = IPBlock(get) # IPBLOCK(get)(self,)
### 輸出O(Output) ###
* write () 響應體
* add_header()新增響應頭
self.add_header('name','張三')
* set_status 設定狀態碼
* 自定義重定向
class RedirctHandler(tornado.web.RequestHandler):
def get(self, *args, **kwargs):
# self.set_status(404,'照比到了')
self.set_status(302,'FOUND')
self.add_header('LOCATION','http://www.bjsxt.com')
* 重定向(302,301)self.redirct(地址)
* 301 永久重定向,
* set_cookie
class CookieHandle(tornado.web.RequestHandler): def get(self,*args,**kwargs): print(self.get_cookie('sessionid','找不到')) import uuid import datetime self.set_cookie('sessionid',str(uuid.uuid4()),expires=datetime.datetime.utcnow()+ datetime.timedelta(minutes=30),path='/coo') self.write('cookie')
* get_cookie
### 生命週期 ###
* initialize--》prepare-->get/post-->on_finish
* initialize和on_finish是一對,如果說initialize初始化工作,on_finish是清理功能。
* url中 (r'/',Handler,字典,name) #字典是給Handler中的initialize方法的
name的使用
class UserHandler(tornado.web.RequestHandler): def get(self, *args, **kwargs): print '使用者沒有登入到重定向login',self.reverse_url('lol') self.redirect(self.reverse_url('lol'))
app = tornado.web.Application([ (r'/user',UserHandler), URLSpec(r'/login',LoginHandler,name='lol'), ])
* write_error 出錯之後,會自動呼叫
* set_default_headers設定預設響應頭
* write_error和set_default_headers 一般寫在父類中,設定通用的響應頭
class DefaultHandler(tornado.web.RequestHandler): def set_default_headers(self): self.add_header('name','hello') self.add_header('age',10) def get(self, *args, **kwargs): self.write('set_default_headers')
class CartHandler(tornado.web.RequestHandler): def get(self, *args, **kwargs): 1/0 會出錯 self.write('測試錯誤') def write_error(self, status_code, **kwargs): print status_code,狀態碼 print kwargs出錯資訊 self.write('伺服器暫時維護中')
### url路由 ###
* 元組
* URLSpec
* 正則,處理類,初始化引數,名字(self.reverse_url('名字'))