Python Twisted

Twsited異步網絡框架

Twisted是一個事件驅動的網絡框架,其中包含了諸多功能,例如:網絡協議、線程、數據庫管理、網絡操作、電子郵件等。

事件驅動

簡而言之,事件驅動分爲二個部分:第一,註冊事件;第二,觸發事件。

例:程序一

#!/usr/bin/env python
# -*- coding:utf-8 -*-

# event_drive.py

event_list = []


def run():
   
for event in event_list:
       
obj = event()
       
obj.execute()


class BaseHandler(object):
   
"""
   
用戶必須繼承該類,從而規範所有類的方法(類似於接口的功能)
   """
   
def execute(self):
       
raise Exception('you must overwrite execute')

程序二,動用程序一

#!/usr/bin/env python
# -*- coding:utf-8 -*-

from source import event_drive


class MyHandler(event_drive.BaseHandler):

   
def execute(self):
       
print 'event-drive execute MyHandler'


event_drive.event_list.append(MyHandler)
event_drive.run()

Protocols

Protocols描述瞭如何以異步的方式處理網絡中的事件。HTTP、DNS以及IMAP是應用層協議中的例子。Protocols實現了IProtocol接口,它包含如下的方法:

makeConnection               在transport對象和服務器之間建立一條連接
connectionMade               連接建立起來後調用
dataReceived                 接收數據時調用
connectionLost               關閉連接時調用

Transports

Transports代表網絡中兩個通信結點之間的連接。Transports負責描述連接的細節,比如連接是面向流式的還是面向數據報的,流控以及可靠性。TCP、UDP和Unix套接字可作爲transports的例子。它們被設計爲“滿足最小功能單元,同時具有最大程度的可複用性”,而且從協議實現中分離出來,這讓許多協議可以採用相同類型的傳輸。Transports實現了ITransports接口,它包含如下的方法:

write                   以非阻塞的方式按順序依次將數據寫到物理連接上
writeSequence           將一個字符串列表寫到物理連接上
loseConnection          將所有掛起的數據寫入,然後關閉連接
getPeer                 取得連接中對端的地址信息
getHost                 取得連接中本端的地址信息

將transports從協議中分離出來也使得對這兩個層次的測試變得更加簡單。可以通過簡單地寫入一個字符串來模擬傳輸,用這種方式來檢查。

例:EchoServer

from twisted.internet import protocol
from twisted.internet import reactor

class Echo(protocol.Protocol):
   
def dataReceived(self, data):   # 只要twisted已收到數據就會把數據返回
       
self.transport.write(data)

def main():
   
factory = protocol.ServerFactory()
   
factory.protocol = Echo

   reactor.listenTCP(1234,factory)
   
reactor.run()

if __name__ == '__main__':
   
main()

EchoClient

from twisted.internet import reactor, protocol

class EchoClient(protocol.Protocol):
   
"""Once connected, send a message, then print the result."""

   
def connectionMade(self):     # 只要建立連接成功就會執行此方法
       
self.transport.write("hello alex!")

   
def dataReceived(self, data):  # 只要收到數據就會調用此方法
       
"As soon as any data is received, write it back."
       
print("Server said:", data)
       
self.transport.loseConnection()  # 如果數據未傳完則等數據傳輸完畢後再調用此方法connectionLost

   
def connectionLost(self, reason):
       
print("connection lost")

class EchoFactory(protocol.ClientFactory):
   
protocol = EchoClient

   def clientConnectionFailed(self, connector, reason):   # 如果連接不上就會調用此方法
       
print("Connection failed - goodbye!")
       
reactor.stop()       # 連接失敗則關閉

   
def clientConnectionLost(self, connector, reason):   # 如果連接過程中斷開則執行此方法
       
print("Connection lost - goodbye!")
       
reactor.stop()     # 連接中斷關閉


# this connects the protocol to a server running on port 8000
def main():
   
f = EchoFactory()
   
reactor.connectTCP("localhost", 1234, f)
   
reactor.run()

# this only runs if the module was *not* imported
if __name__ == '__main__':
   
main()

運行服務器端腳本將啓動一個TCP服務器,監聽端口1234上的連接。服務器採用的是Echo協議,數據經TCP transport對象寫出。運行客戶端腳本將對服務器發起一個TCP連接,回顯服務器端的迴應然後終止連接並停止reactor事件循環。這裏的Factory用來對連接的雙方生成protocol對象實例。兩端的通信是異步的,connectTCP負責註冊回調函數到reactor事件循環中,當socket上有數據可讀時通知回調處理。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章