2008-11-24 66 views
23

我正在尋找一種方式來定期通過連接到TCP端口的所有客戶端發送一些數據。我正在看扭曲的蟒蛇,我知道reactor.callLater。但是,我如何使用它來定期向所有連接的客戶端發送一些數據?數據發送邏輯位於協議類中,並根據需要由反應器實例化。我不知道如何將其從反應堆綁定到所有協議實例...以扭曲協議定期運行函數

回答

37

您可能會想要在工廠中爲連接執行此操作。每次建立連接和丟失都不會自動通知工廠,因此您可以通過協議通知它。

下面是一個完整的示例,說明如何將twisted.internet.task.LoopingCall與自定義的基本工廠和協議結合使用,以宣佈每10秒鐘向每個連接「10秒鐘過去」。

from twisted.internet import reactor, protocol, task 

class MyProtocol(protocol.Protocol): 
    def connectionMade(self): 
     self.factory.clientConnectionMade(self) 
    def connectionLost(self, reason): 
     self.factory.clientConnectionLost(self) 

class MyFactory(protocol.Factory): 
    protocol = MyProtocol 
    def __init__(self): 
     self.clients = [] 
     self.lc = task.LoopingCall(self.announce) 
     self.lc.start(10) 

    def announce(self): 
     for client in self.clients: 
      client.transport.write("10 seconds has passed\n") 

    def clientConnectionMade(self, client): 
     self.clients.append(client) 

    def clientConnectionLost(self, client): 
     self.clients.remove(client) 

myfactory = MyFactory() 
reactor.listenTCP(9000, myfactory) 
reactor.run() 
+0

謝謝!這幫了很多。我試圖處理協議類中的數據發送問題,並且遇到了無法訪問所有客戶端的問題(有一個單獨的類來保存它們!)! 在工廠子類中做這件事更有意義。我會重寫我的代碼... 謝謝! – Amit 2008-11-25 20:18:14

3

我想象最簡單的方法是在客戶端用connectionMade和connectionLost管理協議中的客戶端列表,然後使用LoopingCall請求每個客戶端發送數據。

這感覺有點侵入性,但我認爲你不想在沒有協議控制發送/接收的情況下這樣做。當然,我不得不看你的代碼真正知道它如何適應。有一個Github鏈接? :)

+0

我得到了初始版本的工作。 reactor.callLater可以在任何地方調用,所以我最終從connectionMade()調用它。但是,現在的問題是每個連接都有它自己的計時器和數據。我真的很喜歡一個計時器和數據。 (像廣播)... – Amit 2008-11-25 02:49:17