2013-11-15 28 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()) 

(这只是描述了一个思路的例子,你必须把它扩大到处理的细节。)