摘要:前言俗話說(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)這里
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)行方式如下圖:
因?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ù)走完最后一行代碼后,返回的Future的callback就會(huì)被運(yùn)行(因?yàn)樵?b>Runner中引發(fā)了StopIteration錯(cuò)誤,被set_result了)
* 3.被包裝的函數(shù)是在gen.Runner中運(yùn)行的,而Runner是在ioloop(callback那塊)中運(yùn)行的
代碼非常簡(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
摘要:的非阻塞單線程的特點(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...
摘要:主要是為了實(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)快。...
摘要:要使用協(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。 編...
摘要:譯者說(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...
閱讀 3569·2023-04-25 19:56
閱讀 1676·2021-11-12 10:36
閱讀 1797·2021-11-08 13:19
閱讀 1551·2019-08-30 14:06
閱讀 3044·2019-08-30 11:01
閱讀 1749·2019-08-29 13:23
閱讀 2750·2019-08-29 11:18
閱讀 3435·2019-08-26 13:35