2014-02-25 47 views
0

我最近開始使用Python Twisted,雖然它非常複雜,但我真的很喜歡它!我試圖尋找答案,但我一直在幹,所以我希望有人在這裏是一個扭曲的大師:Python在運行時發送數據包的扭曲動態協議

我有一個大型/複雜的分佈式系統設置的分層格式與主人,奴隸,子從,等。 在我的代碼取決於收到的數據包中的幾個點,我需要發送一個數據包到另一個節點。數據需要發送到的節點在調用reactor.run()之前未知,所以我覺得答案可能會有所不同。我希望連接是可靠的TCP,但它只需要發送一個數據包。有時我需要回復ACK,有時我不需要,但之後連接總是會死掉。目前的辦法,我已經處理這個是通過保持在班裏reactor所需要發送的數據包的引用,並美其名曰:

tmpConn = MyClientFactory(dataToSend) 
self.reactor.connectTCP(ADDR, PORT, tmpConn) 

我覺得這可能然而,存在的幾個問題:

  • 如果我不保留對tmpConn的引用,垃圾回收會發生什麼。
  • 如果我在我的課程中保留對它的引用,它最終會成爲垃圾,因爲它只需要發送一個數據包。

正如我所說的,有很多不同的工廠都在同一時間做這樣的事情,所以我不知道這是否是處理這種情況的最好方法。任何指針都非常感謝。

這是一段代碼,所以問題更加清晰。

from twisted.internet import reactor 
from twisted.internet.protocol import Protocol, Factory, ClientFactory 

class OneShotProtocol(Protocol): 
    def __init__(self, addr, data): 
     self.myaddr = addr 
     self.mydata = data 

    def connectionMade(self): 
     # We know we have a connection here so send the data 
     self.transport.write(self.mydata) 
     # Now we can kill the connection 
     self.transport.loseConnection() 

class OneShotFactory(ClientFactory): 
    def __init__(self, data): 
     self.mydata = data 

    def buildProtocol(self, addr): 
     return OneShotProtocol(addr, self.mydata) 

class ListenProtocol(Protocol): 
    def __init__(self, addr, factory): 
     self.myaddr = addr 
     #NOTE: I only save this because I've read multiple reactors are possible 
     self.factory = factory 

    def dataReceived(self, data): 
     if(data == 'stuff'): 
      #Alert the other node! 
      tmpConn = OneShotFactory('The British are coming') 
      self.factory.reactor.connectTCP(ADDR, PORT, tmpConn) 
     # Moving on... 

class ListenFactory(Factory): 
    def __init__(self, reactor): 
     self.reactor = reactor 

    def buildProtocol(self, addr): 
     return OneShotProtocol(addr, self) 

l = ListenFactory(reactor) 
reactor.listenTCP(PORT, l) 
reactor.run() 

回答

0

這聽起來像是一種實現所需行爲的好方法。

您不必非常擔心工廠的垃圾收集。反應堆會保留一個參考(畢竟,你通過它到connectTCP),只要它需要,然後忘記它。如果你也忘記了它,那麼Python的垃圾回收器會在太久之前爲你清理它。

您可能想要做的唯一調整是使用酷新的"endpoint" APIs而不是使用connectTCP目錄。這並沒有改變解決方案的基本思想,它只是給你一點靈活性,你可能有一天會從中受益。

相關問題