2012-11-30 23 views
0

我採取以下基本結構的API:如何在扭曲的服務器上建立無阻塞的連接?

  1. 運行serverA的
  2. 客戶端連接到ServerA和發送數據
  3. 服務器A處理數據並將其發送到serverB上
  4. 服務器B回覆serverA
  5. ServerA響應客戶端的請求,基於從服務器B收到的輸入

到目前爲止,我已經嘗試了兩種解決方案:

1)使用httplib創建一個標準的非扭曲TCP連接來處理從serverA到serverB的請求。但是,這會在httplib調用期間有效地阻止服務器。

2)創建的第二類從protocol.Protocol繼承和使用

factory = protocol.ClientFactory() 
factory.protocol = Authenticate 
reactor.connectSSL("localhost",31337,factory, ssl.ClientContextFactory()) 

創建ServerA和serverB上之間的連接。但是,當這樣做時,我似乎無法從請求類的回調中訪問原始客戶端到服務器的連接。

在Twisted中處理這種設置的正確方法是什麼?

回答

2

「client-to-serverA」連接由與傳輸關聯的協議實例表示。這些都是普通的舊Python對象,所以你可以做一些事情,比如將它們作爲參數傳遞給函數或類初始化器,或者將它們設置爲其他對象的屬性。

舉例來說,如果你有ClientToServerAProtocol一個fetchServerBData方法,其響應來自客戶端接收一些字節調用時,你可能會寫這樣的:

class ClientToServerAProtocol(Protocol): 
    ... 
    def fetchServerBData(self, anArg): 
     factory = protocol.ClientFactory() 
     factory.protocol = Authenticate 
     factory.clientToServerAProtocol = self 
     reactor.connectSSL("localhost",31337, factory, ssl.ClientContextFactory()) 

由於ClientFactory套本身作爲它創建的任何協議上的factory屬性,將由此產生的Authenticate實例將能夠說`self.factory.clientToServerAProtocol並獲得對該「client-to-serverA」連接的引用。

這種方法有很多變化。這裏是另外一個使用最近推出的端點API:

from twisted.internet.endpoints import SSL4ClientEndpoint 

class ClientToServerAProtocol(Protocol): 
    ... 
    def fetchServerBData(self, anArg): 
     e = SSL4ClientEndpoint(reactor, "localhost", 31337, ssl.ClientContextFactory()) 
     factory = protocol.Factory() 
     factory.protocol = Authenticate 
     connectDeferred = e.connect(factory) 
     def connected(authProto): 
      authProto.doSomethingWith(self) 
     connectDeferred.addCallback(connected) 

基本相同的位置的想法 - 用self給予了「客戶端到serverA的」連接你感興趣的Authenticate協議的參考。在這裏,我使用了一個嵌套函數來''關閉''self。這只是獲得參考到程序正確部分的許多選項中的另一個選項。