扭曲的回调循环阻止接收更多数据
Twisted callback loop blocking further data from being recieved
当回调循环在 Twisted 中 运行ning 时,我的印象是 reactor 仍然能够 send/receive 来自服务器的数据,因为它能够运行 'between' 回调。但是,当我 运行 下面的脚本时,它完全忽略了 self.transport.write()
行。服务器只是 Twisted 在其网站上的基本回显服务器。
from twisted.internet import reactor, protocol
from twisted.internet.defer import Deferred
class EchoClient(protocol.Protocol):
deferred = Deferred()
def connectionMade(self):
self.deferred.addCallback(self.doThing)
self.deferred.callback(0)
def doThing(self, _):
print 'xxx'
self.transport.write('Hello, world!')
self.deferred.addCallback(self.doThing)
def dataReceived(self, data):
"As soon as any data is received, write it back."
print "Server said:", data
self.transport.loseConnection()
class EchoFactory(protocol.ClientFactory):
protocol = EchoClient
def main():
f = EchoFactory()
reactor.connectTCP('192.168.0.7', 8000, f) # Correctly connected to my server
reactor.run()
if __name__ == '__main__':
main()
我预计会打印一个或什至几个 'xxx's,然后服务器将 'Hello, world!' 的回显发送回给我,然后再发送更多 'xxx's。相反,我得到的是 'xxx' 的无限滚动,甚至没有尝试将 'Hello, world!' 发送到服务器。我是什么missing/misunderstanding?
问题是您的示例从不让主循环 运行。
建立连接后,您向 self.deferred
添加回调 - 我不确定 self.deferred
应该代表什么操作,但显然没有任何用处。
然后你立即(同步)回拨self.deferred
。这会立即执行 doThing
,它会调用 self.transport.write
。这会在主循环下一个 运行s 时将一些字节添加到要发送的传出缓冲区。然后,在该回调中,您立即(同步)向 self.deferred
添加另一个回调,一旦当前回调完成,该回调将 运行 。所以我们进入 doThing
,它调用 self.transport.write
。我们还没有写任何东西,更不用说读取任何东西来传递给 dataReceived
,因为我们还没有回到主循环。但是我们向 Deferred
添加了另一个回调。再次调用 doThing
。
这会一直持续下去,在缓冲不断增加的传出流量时在传输上分配无限量的内存,但绝不允许程序从 connectionMade
return,使它回到主循环,等待可写性和可读性事件。
我不知道如何修复此程序,因为不清楚您尝试做什么,但无论如何,这不是办法:).
当回调循环在 Twisted 中 运行ning 时,我的印象是 reactor 仍然能够 send/receive 来自服务器的数据,因为它能够运行 'between' 回调。但是,当我 运行 下面的脚本时,它完全忽略了 self.transport.write()
行。服务器只是 Twisted 在其网站上的基本回显服务器。
from twisted.internet import reactor, protocol
from twisted.internet.defer import Deferred
class EchoClient(protocol.Protocol):
deferred = Deferred()
def connectionMade(self):
self.deferred.addCallback(self.doThing)
self.deferred.callback(0)
def doThing(self, _):
print 'xxx'
self.transport.write('Hello, world!')
self.deferred.addCallback(self.doThing)
def dataReceived(self, data):
"As soon as any data is received, write it back."
print "Server said:", data
self.transport.loseConnection()
class EchoFactory(protocol.ClientFactory):
protocol = EchoClient
def main():
f = EchoFactory()
reactor.connectTCP('192.168.0.7', 8000, f) # Correctly connected to my server
reactor.run()
if __name__ == '__main__':
main()
我预计会打印一个或什至几个 'xxx's,然后服务器将 'Hello, world!' 的回显发送回给我,然后再发送更多 'xxx's。相反,我得到的是 'xxx' 的无限滚动,甚至没有尝试将 'Hello, world!' 发送到服务器。我是什么missing/misunderstanding?
问题是您的示例从不让主循环 运行。
建立连接后,您向 self.deferred
添加回调 - 我不确定 self.deferred
应该代表什么操作,但显然没有任何用处。
然后你立即(同步)回拨self.deferred
。这会立即执行 doThing
,它会调用 self.transport.write
。这会在主循环下一个 运行s 时将一些字节添加到要发送的传出缓冲区。然后,在该回调中,您立即(同步)向 self.deferred
添加另一个回调,一旦当前回调完成,该回调将 运行 。所以我们进入 doThing
,它调用 self.transport.write
。我们还没有写任何东西,更不用说读取任何东西来传递给 dataReceived
,因为我们还没有回到主循环。但是我们向 Deferred
添加了另一个回调。再次调用 doThing
。
这会一直持续下去,在缓冲不断增加的传出流量时在传输上分配无限量的内存,但绝不允许程序从 connectionMade
return,使它回到主循环,等待可写性和可读性事件。
我不知道如何修复此程序,因为不清楚您尝试做什么,但无论如何,这不是办法:).