Dom*_*ane 6 python networking twisted
在Twisted中有1天的经验我尝试安排消息发送以回复tcp客户端:
import os, sys, time
from twisted.internet import protocol, reactor
self.scenario = [(1, "Message after 1 sec!"), (4, "This after 4 secs"), (2, "End final after 2 secs")]
for timeout, data in self.scenario:
reactor.callLater(timeout, self.sendata, data)
print "waited %d time, sent %s\n"%(timeout, data)
Run Code Online (Sandbox Code Playgroud)
现在它发送消息,但我有2个问题:
1)"超时"从"现在"开始,我想在每个上一个任务完成后计算它(之前的消息被发送)
2)我不知道如何发送所有消息后关闭连接.如果我放在s self.transport.loseConnection()之后callLater立即关闭连接.
在以前的尝试我没有用reactor.callLater,但只self.transport.write()和time.sleep(n)在for循环.在这种情况下,所有消息都在所有超时后一起发送...不是我想要的东西.
目的是等待客户端连接,等待timeout1并发送message1,等待timeout2并发送message2,...等.最后消息后 - 关闭连接.
使用Twisted时要意识到的重要一点是没有任何东西可以等待.当你打电话时reactor.callLater(),你要求反应堆稍后再打电话,而不是现在.呼叫立即结束(在呼叫被安排之后,在执行之前完成.)因此,你的print陈述是谎言:你没有等待timeout时间; 你根本没有等.
您可以通过多种方式修复它,使用哪种方式取决于您的实际需求.如果您希望第二个任务在第一个任务开始后四秒钟启动,您只需将第一个任务的延迟(您的timeout变量)添加到第二个任务的延迟.但是,第一项任务可能无法在您安排时完全启动; 它可能会在稍后开始,如果Twisted太忙而不能早点启动它.此外,如果您的任务需要很长时间,则可能无法在第二个任务开始之前完成.
更常见的方法是第一个任务是安排第二个任务,而不是立即安排第二个任务.您可以结束(通过调用第一个任务后安排其4秒reactor.callLater()在第一任务结束),或四秒第一个任务开始后(通过调用reactor.callLater()在开始的第一个任务),或执行更复杂的计算来确定什么时候开始,跟踪经过的时间.
当您在Twisted等待中没有意识到任何事情时,在执行所有计划任务时处理关闭连接变得很容易:您只需要完成上次任务调用self.transport.loseConnection().对于更复杂的情况,您可能希望将Deferreds链接在一起,或者使用a DeferredList来执行loseConnection()所有挂起任务的完成时间,即使它们不是严格顺序的.