天天看點

《Python核心程式設計(第3版)》——2.6 *Twisted架構介紹

本節書摘來自異步社群《python核心程式設計(第3版)》一書中的第2章,第2.6節,作者[美] wesley chun(衛斯理 春),孫波翔 李斌 李晗 譯,更多章節内容可以通路雲栖社群“異步社群”公衆号檢視。

twisted是一個完整的事件驅動的網絡架構,利用它既能使用也能開發完整的異步網絡應用程式和協定。在編寫本書時,因為它還不是python标準庫的一部分,是以必須單獨下載下傳并安裝它(可以使用本章末尾的連結)。它提供了大量的支援來建立完整的系統,包括網絡協定、線程、安全性和身份驗證、聊天/ im、dbm及rdbms資料庫內建、web/網際網路、電子郵件、指令行參數、gui內建工具包等。

使用twisted來實作簡單的例子,有點小題大做,但是你必須開始使用它,并且該應用程式就相當于網絡應用程式的“hello world”。

與socketserver類似,twisted的大部分功能都存在于它的類中。特别是對于該示例,我們将使用twisted網際網路元件中的reactor和protocol子包中的類。

你會發現示例2-10中的代碼類似于socketserver例子中的代碼。然而,相比于處理程式類,我們建立了一個協定類,并以與安裝回調相同的方式重寫了一些方法。另外,這個例子是異步的。現在就讓我們看一下伺服器代碼。

示例2-10 twisted reactor時間戳tcp伺服器(tstservtw.py)

《Python核心程式設計(第3版)》——2.6 *Twisted架構介紹

逐行解釋

第1~6行

設定行代碼包括常用子產品導入,尤其是twisted.internet的protocol和reactor子包以及常數端口号的設定。

第8~14行

我們獲得protocol類并為時間戳伺服器調用tsservprotocol。然後重寫了connectionmade()和datareceived()方法,當一個用戶端連接配接到伺服器時就會執行connectionmade()方法,而當伺服器接收到用戶端通過網絡發送的一些資料時就會調用datareceived()方法。reactor會作為該方法的一個參數在資料中傳輸,這樣就能在無須自己提取它的情況下通路它。

此外,傳輸執行個體對象解決了如何與用戶端通信的問題。你可以看到我們如何在connectionmade()中使用它來擷取主機資訊,這些是關于與我們進行連接配接的用戶端的資訊,以及如何在datareceived()中将資料傳回給用戶端。

第16~20行

在伺服器代碼的最後部分中,建立了一個協定工廠。它之是以被稱為工廠,是因為每次得到一個接入連接配接時,都能“制造”協定的一個執行個體。然後在reactor中安裝一個tcp監聽器,以此檢查服務請求。當它接收到一個請求時,就會建立一個tsservprotocol執行個體來處理那個用戶端的事務。

與socketserver tcp用戶端不同,示例2-11看起來與其他用戶端都不同,這個是明顯的twisted。

示例2-11 twisted reactor時間戳tcp用戶端(tstclnttw.py)

《Python核心程式設計(第3版)》——2.6 *Twisted架構介紹

再一次,除了導入twisted元件之外,并沒有什麼新内容。它與其他的用戶端非常類似。

第8~22行

類似于伺服器,我們通過重寫connectionmade()和datareceived()方法來擴充protocol,并且這兩者都會以與伺服器相同的原因來執行。另外,還添加了自己的方法senddata(),當需要發送資料時就會調用它。

因為這次我們是用戶端,是以我們是開啟與伺服器對話的一端。一旦建立了連接配接,就進行第一步,即發送一條消息。伺服器回複之後,我們就将接收到的消息顯示在螢幕上,并向伺服器發送另一個消息。

以上行為會在一個循環中繼續,直到當提示輸入時我們不輸入任何内容來關閉連接配接。此時,并非調用傳輸對象的write()方法發送另一個消息到伺服器,而是執行loseconnection()來關閉套接字。當發生這種情況時,将調用工廠的clientconnectionlost()方法以及停止reactor,結束腳本執行。此外,如果因為某些其他的原因而導緻系統調用了clientconnectionfailed(),那麼也會停止reactor。

在腳本的最後部分建立了一個用戶端工廠,建立了一個到伺服器的連接配接并運作reactor。注意,這裡執行個體化了用戶端工廠,而不是将其傳遞給reactor,正如我們在伺服器上所做的那樣。這是因為我們不是伺服器,需要等待用戶端與我們通信,并且它的工廠為每一次連接配接都建立一個新的協定對象。因為我們是一個用戶端,是以建立單個連接配接到伺服器的協定對象,而伺服器的工廠則建立一個來與我們通信。

與其他用戶端類似,twisted用戶端也展示了輸出。

伺服器恢複到單個連接配接。twisted會保持連接配接,在每條消息發送後不會關閉傳輸。

“connection from”的輸出并不包含其他資訊,因為我們隻從伺服器傳輸對象的getpeer()方法請求了主機/位址。

需要記住的是,大多數基于twisted的應用程式都比本節給出的例子更加複雜。因為這是一個功能豐富的庫,但是它确實有一定的複雜度,是以你需要做好準備。