1. 程式人生 > >初學Tornado框架以及和Django的對比

初學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('名字'))