来自现有阻塞代码的扭曲TCP客户端的重构
-
20-12-2019 - |
题
我有一个python程序,目前使用TCP / IP客户端模块,我编写了从流式服务器接收数据。服务器输出数据行。
我的TCP客户类是相当原始的,我想重构使用扭曲的重新连接clientfactory。
主程序当前从我的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
.
但我认为这是一种过度简化。
总结,我正在尝试的是实现一个扭曲的重新连接的TCP客户端,它表现出类似于我的ReadLines方法,并且可以或多或少地访问:
for msg_buffer in self.twistedTcpClient.readLines():
.
任何指针都将非常感谢
更新: 我刚刚偶然发现了扭曲的“钩针”。乍一看曲奇似乎是专为我需要的那种模型而设计的......我会在一些测试后报告
解决方案
扭曲的方式是写一个协议。而不是做:
for line in self.twistedTcpClient.readLines():
process_line(line) ...
.
您会写下您的协议(也许通过子类化世代odicetagcode):
class MyProtocol(LineReceiver):
...
def lineReceived(self, line):
process_line(line) ...
.
要重新推荐代码以使用twisted.protocols.basic.LineReceiver
回调而不是具有迭代循环。
写了什么:
for line in self.twistedTcpClient.readLines():
process_line(line) ...
.
是有问题的,因为扭曲是异步的。在等待世等待世代古代码的方法时,无法扭转到其他任何事情。
我建议写一个协议,但如果你真的坚持拥有这个迭代器模式,那么你就可以这样做:@inlineCallbacks
def my_func():
while True:
try:
line = yield self.twistedTcpClient.getNextLine()
except StopIteration:
break
process_line(line) ...
.
现在,棘手的事情是为每个调用getnextline()制作生成的return lineReceived
。也许这样的东西:
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())
.
(这只是一个示例,说明了这个想法,你必须扩展它来处理细节。)
不隶属于 StackOverflow