成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

實(shí)踐,用tornado實(shí)現(xiàn)自定義協(xié)議server

wizChen / 1836人閱讀

摘要:前言俗話說(shuō)光說(shuō)不練假把式上一篇文里都只是光看著別人的源碼說(shuō)貌似有點(diǎn)紙上談兵的意思所以這次寫(xiě)一個(gè)簡(jiǎn)單的自己定義協(xié)議的既可以熟悉和的用法又可以在去除了復(fù)雜的協(xié)議后了解的工作原理代碼不多加上空行和也就行不到在上的源碼點(diǎn)這里目標(biāo)定義一個(gè)簡(jiǎn)單的協(xié)議達(dá)

前言

俗話說(shuō)"光說(shuō)不練假把式",上一篇文里都只是光看著別人的源碼說(shuō),貌似有點(diǎn)紙上談兵的意思.
所以這次寫(xiě)一個(gè)簡(jiǎn)單的,自己定義協(xié)議的server.
既可以熟悉Future和coroutine的用法,又可以在去除了復(fù)雜的http協(xié)議后,了解tornado的工作原理.
代碼不多,加上空行和import也就200行不到.
在github上的源碼點(diǎn)這里

目標(biāo)

1.定義一個(gè)簡(jiǎn)單的協(xié)議,達(dá)到遠(yuǎn)程調(diào)用的效果,并且是個(gè)長(zhǎng)連接的協(xié)議(類(lèi)似websock)

2.模仿tornado的框架模式開(kāi)發(fā)這個(gè)server框架,讓用戶代碼開(kāi)發(fā)方便,并且支持coroutine

3.為了省去客戶端的開(kāi)發(fā),客戶端使用telnet

協(xié)議

1.客戶端連接成后,以換行符分割每次通信內(nèi)容

2.第一次通信內(nèi)容是需要執(zhí)行handler名稱,第二次通信的內(nèi)容是該handler的方法名

3.對(duì)于客戶端的主動(dòng)close,需等待此連接所有的異步操作完成后才關(guān)閉連接
最后運(yùn)行方式如下圖:

源碼說(shuō)明 總覽

因?yàn)橄胱尨a盡量少,所以委托模式?jīng)]有嚴(yán)格按照設(shè)計(jì)模式的規(guī)范寫(xiě),直接忽略掉了interface的定義.嚴(yán)格來(lái)說(shuō)是需要定義interface和判斷傳入?yún)?shù)的類(lèi)型的(泛華)
這是類(lèi)的實(shí)例關(guān)系圖(也不知道是不是這樣畫(huà)...)

MyServer和MyApplication的實(shí)例常駐.一個(gè)連接進(jìn)來(lái)后就會(huì)創(chuàng)建圖中其他的實(shí)例各一個(gè).

異步說(shuō)明

1.為了達(dá)到目標(biāo)中的第一點(diǎn),需要一個(gè)while循環(huán),讀取了客戶端數(shù)據(jù)后,執(zhí)行handler,
立即繼續(xù)讀取下一條客戶端數(shù)據(jù).直到客戶端關(guān)閉操作,引發(fā)StreamClosedError才退出循環(huán)

2.為了達(dá)到目標(biāo)中的第二點(diǎn),判斷handler的返回值,如果類(lèi)型是Future則yield處理,因?yàn)楸痉椒ㄓ?b>@gen.coroutine,所以yield就代表異步操作是在gen.Runner中執(zhí)行的.

3.為了達(dá)到目標(biāo)中的第三點(diǎn),需要記錄每一個(gè)異步操作,并且異步操作完成后移除.當(dāng)客戶端主動(dòng)關(guān)閉連接時(shí),需判斷是否還有future未完成.所以close代碼中給每個(gè)future加上done_callback,用以檢查關(guān)閉

詳情見(jiàn)代碼 MyServerConnection._server_request_loop

@gen.coroutine
    def _server_request_loop(self, delegate):
        try:
            #get request adepter
            request_delegate = delegate.on_request(self)
            while True:

                try:
                    message_future = self.stream.read_until_regex(b"

?")
                    message = yield message_future
                    message = self._parse_data(message)

                except (iostream.StreamClosedError, 
                        iostream.UnsatisfiableReadError):
                    app_log.error(" close the connect")
                    self.close()
                    return

                except Exception:

                    gen_log.error("Uncaught exception", exc_info=True)
                    self.close()
                    return

                ret = request_delegate.on_message(message)
                #如果是異步執(zhí)行的方法,保存future,用于確保close時(shí),所有future都已完成
                if isinstance(ret, Future):
                    ret.add_done_callback(lambda f:self._serving_futures.remove(f))
                    self._serving_futures.append(ret)

        finally:
            delegate.on_close(self)
    def close(self):

        def mayby_close(f):
            futures = self._serving_futures+self._pending_writes
            app_log.error(futures)
            if not any(futures):
                self.stream.close()

        pending_futrues = self._serving_futures+self._pending_writes
        if any(pending_futrues):
            map(lambda f:f.add_done_callback(mayby_close),pending_futrues)
        else:
            self.stream.close()
關(guān)于@coroutine

其實(shí)用@coroutine的時(shí)候只需要記住幾點(diǎn)就行了
* 1.被包裝的函數(shù)(方法),返回值是Future,
* 2.被包裝的函數(shù)走完最后一行代碼后,返回的Futurecallback就會(huì)被運(yùn)行(因?yàn)樵?b>Runner中引發(fā)了StopIteration錯(cuò)誤,被set_result了)
* 3.被包裝的函數(shù)是在gen.Runner中運(yùn)行的,而Runner是在ioloop(callback那塊)中運(yùn)行的

總結(jié)

代碼非常簡(jiǎn)單,因?yàn)?b>tornado為我們提供了異步的庫(kù)(tornado真強(qiáng)大,協(xié)程好厲害!!),并且是單進(jìn)程的編程,不需要考慮鎖,寫(xiě)起來(lái)就更輕松了.
最后附上程序效果圖

廢話

這只是個(gè)吃飽撐著的程序,一點(diǎn)實(shí)際作用都沒(méi)啊(好想被拍死!).吃飽撐著的原因是我還沒(méi)下決心去找工作...工作太難找啦(哭~~)!!!!好想被帶走.................

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/37587.html

相關(guān)文章

  • [零基礎(chǔ)學(xué)python]Hello,第一個(gè)網(wǎng)頁(yè)分析

    摘要:的非阻塞單線程的特點(diǎn)在這個(gè)模塊中體現(xiàn)。還有一個(gè)模塊引入,是用完成的這兩句就顯示了所謂命令行解析模塊的用途了。表示可以接收來(lái)自的請(qǐng)求了。以上把一個(gè)簡(jiǎn)單的剖析。 As he walked by the sea of Galilee, he saw two brothers, Simon, who is called Peter, and Andrew his brother, cas...

    Steve_Wang_ 評(píng)論0 收藏0
  • tornado配合celery及rabbitmq實(shí)現(xiàn)web request異步非阻塞

    摘要:主要是為了實(shí)現(xiàn)系統(tǒng)之間的雙向解耦而實(shí)現(xiàn)的。問(wèn)題及優(yōu)化隊(duì)列過(guò)長(zhǎng)問(wèn)題使用上述方案的異步非阻塞可能會(huì)依賴于的任務(wù)隊(duì)列長(zhǎng)度,若隊(duì)列中的任務(wù)過(guò)多,則可能導(dǎo)致長(zhǎng)時(shí)間等待,降低效率。 Tornado和Celery介紹 1.Tornado Tornado是一個(gè)用python編寫(xiě)的一個(gè)強(qiáng)大的、可擴(kuò)展的異步HTTP服務(wù)器,同時(shí)也是一個(gè)web開(kāi)發(fā)框架。tornado是一個(gè)非阻塞式web服務(wù)器,其速度相當(dāng)快。...

    番茄西紅柿 評(píng)論0 收藏0
  • 己寫(xiě)一個(gè) wsgi 服務(wù)器運(yùn)行 Django 、Tornado 等框架應(yīng)

    摘要:要使用協(xié)議我們不可能自己實(shí)現(xiàn)一個(gè),現(xiàn)在比較流行的解決方案就是使用套接字編程,已經(jīng)幫我們實(shí)現(xiàn)了協(xié)議的細(xì)節(jié),我們可以直接拿來(lái)使用不用關(guān)心細(xì)節(jié)。 前幾天寫(xiě)了 淺談cgi、wsgi、uwsgi 與 uWSGI 等一些 python web 開(kāi)發(fā)中遇到的一些名詞的理解,今天博主就根據(jù) wsgi 標(biāo)準(zhǔn)實(shí)現(xiàn)一個(gè) web server,并嘗試用它來(lái)跑 Django、tornado 框架的 app。 編...

    lunaticf 評(píng)論0 收藏0
  • Tornado 4.3文檔翻譯: web框架-RequestHandler和Application

    摘要:譯者說(shuō)于年月日發(fā)布,該版本正式支持的關(guān)鍵字,并且用舊版本編譯同樣可以使用這兩個(gè)關(guān)鍵字,這無(wú)疑是一種進(jìn)步。其次,這是最后一個(gè)支持和的版本了,在后續(xù)的版本了會(huì)移除對(duì)它們的兼容。本節(jié)最好直接在或者閱讀,以獲得更好的閱讀體驗(yàn)格式支持。 譯者說(shuō) Tornado 4.3于2015年11月6日發(fā)布,該版本正式支持Python3.5的async/await關(guān)鍵字,并且用舊版本CPython編譯Torn...

    xiongzenghui 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<