2013-11-15 62 views
3

我有一個python程序,目前使用我寫的tcp/ip客戶端模塊從流服務器接收數據。服務器輸出數據行。從現有的阻塞代碼重構扭曲的TCP客戶端

我的TCP客戶端類是相當原始的,我想重構使用扭曲的ReconnectingClientFactory。

當前主程序從我的TCP客戶端中的readLines函數中獲取數據,這些數據在收到時產生這些行。

的TCP客戶機方法是通過訪問:

for msg_buffer in self.myTcpClient.readLines(): 
    do some stuff with the data in msg_buffer 

在我的TCP客戶端在本質上是readlines方法方法是這樣的:

while True: 
    newLine = self.sock.recv(self.buffer_size) 
    yield newLine 

當我執行扭曲客戶端我會想一些方法因爲它表現爲迭代器併產生數據。我假設我會在協議dataReceived方法中做一些事情。

我很想弄明白這是如何工作的。在我看來,扭曲的延期是爲了這種用途,但我無法弄清楚如何使用延期達到我的目的(如果我關於延期的假設是正確的)。

在一個完美的世界中,扭曲的客戶端會產生收到的行,所以類似於目前的方法可以完成這項工作。即

class GetData(protocol): 
    def dataReceived(self, data): 
     yield data 

但我認爲這是過於簡單化。

綜上所述,我想要做的就是實現一個行爲有點像我的readlines方法方法,並且可以訪問或多或少像一個扭曲的重新連接TCP客戶端:

for msg_buffer in self.twistedTcpClient.readLines(): 

任何指針會大加讚賞

更新: 我只是偶然發現了'鉤針'扭曲。乍一看,鉤針似乎已經被設計爲我需要的那種模型......我會在一些測試後報告回來

+0

你會更容易,如果你得到的反饋可以使您的帖子主題更具描述性的問題。 – ASGM

+1

謝謝ASGM - 我已經更新了主題並添加了一條備註:鉤針編號 – RoyHB

+0

如果您可以包含完整的可運行程序而不是片段,這也會很有幫助。如果不仔細查看完整的綜合程序,很難確定自己的要求。有關更多信息,請參閱http://sscce.org。 – Glyph

回答

1

這樣做的扭曲方式是編寫一個協議。而不是做:

for line in self.twistedTcpClient.readLines(): 
    process_line(line) ... 

你會寫你的協議(可能通過繼承一個twisted.protocols.basic.LineReceiver):

class MyProtocol(LineReceiver): 
    ... 
    def lineReceived(self, line): 
     process_line(line) ... 

你要重構代碼使用lineReceived回調,而不是有一個迭代循環。

什麼你寫:

for line in self.twistedTcpClient.readLines(): 
    process_line(line) ... 

是有問題的扭曲是異步的。 Twisted無法在等待twistedTcpClient.readLines()方法時執行其他任何操作。

我建議寫一個協議,但如果你真的堅持有此迭代器模式,那麼你可以這樣做:

@inlineCallbacks 
def my_func(): 
    while True: 
     try: 
      line = yield self.twistedTcpClient.getNextLine() 
     except StopIteration: 
      break 

     process_line(line) ... 

現在,棘手的事情是讓twistedTcpClient每次退貨Deferreds調用getNextLine()。也許是這樣的:

class MyProtocol(LineReceiver): 
    ... 
    def getNextLine(self): 
     self.defer_given_out = Deferred() 

    def lineReceived(self, line): 
     self.defer_given_out.callback(line) 

    def connectionLost(self): 
     self.defer_given_out.errback(StopIteration()) 

(這只是描述了一個思路的例子,你必須把它擴大到處理的細節。)