Twisted定義
? ??Twisted是一個基于事件驅動的網絡引擎框架
? ? ?網絡框架,別人預先定義好的一個框架(一個項目),如.net某個web框架有25個class,從BeginRequest依次執行類里的process方法,程序員自己定義一個類,添加到框架里,應用程序從上到下運行,就會執行自定義代碼。框架只知道這個類的列表,不關心你寫了什么內容,從上到下執行,類似于一個執行鏈,C#里叫委托鏈。也就是把代碼類放到這個列表中,委托這個框架替你執行。
? ? 事件驅動(not event),把自定義代碼注冊到框架中,框架代替你執行。或者框架提供幾個接口,讓你插入數據(python里沒有 )。
????委托不能為空,事件可以為空。
演示一個最簡單的框架
前期準備:
? ? ?新建一個名為event_drive的python package,里面新建一個event_drive.py文件,這個就是框架主文件,把package目錄復制到sys.path中,如:c:\python27\lib\site-package\
event_drive.py:
1 2 3 4 5 6 7 8 9 10 11 12 13 | event_list = [] ? ?#[myclass,] def run(): ???? for event in event_list: ???????? obj = event() ???????? obj.execute() class BaseHandler( object ): ???? """ ???? 用戶必須繼承該類,從而規范所有類的方法(類似于接口的功能) ???? """ ???? def execute( self ): ???????? raise Exception( 'you must overwrite execute' ) |
自定義代碼:
1 2 3 4 5 6 7 8 9 | from event_drive import event_drive class MyClass(event_drive.BaseHandler): ???? def execute( self ):? #重寫execute方法 ???????? print "執行了自定義execute方法" event_drive.event_list.append(MyClass)? #注冊到委托鏈即“注冊一個事件” event_drive.run() |
執行過程: ? ?
導入event_drive文件夾中的event_drive文件
自定義一個類MyClass,這個類繼承了event_drive文件中BaseHandler類
類里實現execute方法,內容無所謂甚至可以為空,方法名稱execute不能改變
注冊事件到框架的委托鏈,即把類名list.append(MyClass)傳進去(下面的Twisted框架是創建對象后改一個字段為類名也是同樣的目的)
執行run方法,框架自己就把MyClass中的方法執行了
執行結果:
1 2 | 執行了自定義execute方法 Process finished with exit code 0 |
Twisted框架:以socket為例
安裝Twisted:(linux參考如下,windows直接用安裝包)
1 2 3 | cd Twisted-15.5.0 python setup.py build python setup.py install |
? ? ps:twisted調用了zope和win32api模塊,先安裝這兩個,要不會報錯。
Twisted_server.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | from twisted.internet import reactor, protocol from twisted.web.client import getPage from twisted.internet import reactor import time class Echo(protocol.Protocol): ? ?#繼承protocol.py中的Protocol類 ???? def dataReceived( self , data): ? ? ???????? self .transport.write(data) ? ?#將收到的內容直接發送回去 factory = protocol.ServerFactory() ? ?#實例化 factory.protocol = Echo ? ?#將自定義類傳給對象 reactor.listenTCP( 8000 ,factory) ? ?#將端口和實例化對象作為參數傳給reactor reactor.run() |
Twisted_client.py
1 2 3 4 5 6 7 8 9 10 11 12 | import socket ip_port = ( '127.0.0.1' , 8000 ) sk = socket.socket() sk.connect(ip_port) sk.settimeout( 5 ) while True : ???? inp = raw_input ( "please input:" ) ???? sk.sendall(inp) ???? print sk.recv( 1024 ) sk.close() |
執行原理
? ? 跟SocketServer原理類似,內部封裝,內部有一個while循環,while循環一旦觸發,找到這個類,執行這個類的構造方法,創建對象,通過對象,執行預定義的方法,
源碼分析
程序執行流程:
- 運行服務端程序
創建Protocol的派生類Echo
? ? 解釋:自定義Echo類,名字隨便起,它繼承了Protocol類,Protocol類又繼承了BaseProtocol類,有了最左邊的圖
創建ServerFactory對象,并將Echo類封裝到其protocol字段中
? ? 解釋:ServerSocket是將MyClass以參數的形式封裝,這個是以字段的形式
執行reactor的 listenTCP 方法,內部使用?tcp.Port 創建socket server對象,并將該對象添加到了 reactor的set類型的字段 _read 中
? ? 解釋:
print type(reactor)
==>
<class 'twisted.internet.selectreactor.SelectReactor'>
去selectreactor.SelectReactor中找listenTCP,看上面的類繼承關系圖,繼承了好多類。listenTCP和run方法都在基類里。
def listenTCP(self, port, factory, backlog=50, interface=''):
p = tcp.Port(port, factory, backlog, interface, self)
p.startListening()
return p
其中把factory對象傳入,就相當于:1、把Echo類封裝到factory字段2、再把factory對象封裝到listenTCP3、tcp.port里創建了socket連接執行reactor的 run 方法,內部執行 while 循環,并通過 select 來監視?_read 中文件描述符是否有變化,循環中...
? ? 解釋:SelectReactor中包含兩個集合_reads=set()和_writes=set(),不允許重復的集合,有連接后把文件句柄添加到這個集合中。開始執行reactor.run(),它調用基類里的mainLoop方法,又調取的selectreactor.doInteration,找不到?因為它是個重命名doInteration=doSelect,這個方法里面調取的就是select方法,通過調用select,循環這個_reads。一旦有句柄進來,通過反射去_reads里找“doRead”執行方法。
客戶端請求到達
? ? ? ? ?解釋:可以通過debug方式了解調用順序
- 執行reactor的?_doReadOrWrite 方法,其內部通過反射調用 tcp.Port 類的?doRead 方法,內部 accept 客戶端連接并創建Server對象實例(用于封裝客戶端socket信息)和?創建 Echo 對象實例(用于處理請求)?,然后調用 Echo 對象實例的?makeConnection 方法,創建連接。
- 執行 tcp.Server 類的?doRead 方法,讀取數據,
- 執行 tcp.Server 類的?_dataReceived 方法,如果讀取數據內容為空(關閉鏈接),否則,觸發Echo 的?dataReceived 方法
- 執行?Echo 的?dataReceived 方法
功能
????Twisted主要用于網絡操作,它支持許多常見的傳輸及應用層協議,包括TCP、UDP、SSL/TLS、HTTP、IMAP、SSH、IRC以及FTP。其中包含了諸多功能,例如:網絡協議、線程、數據庫管理、網絡操作、電子郵件等。
優點
使用基于事件驅動的編程模型,而不是多線程模型。
跨平臺:為主流操作系統平臺暴露出的事件通知系統提供統一的接口。
“內置電池”的能力:提供流行的應用層協議實現,因此Twisted馬上就可為開發人員所用。
符合RFC規范,已經通過健壯的測試套件證明了其一致性。
能很容易的配合多個網絡協議一起使用。
可擴展。
一個非常全面介紹Twisted網站
? ??http://twisted.readthedocs.org/en/twisted-15.5.0/