我想使用twisted(和StarPy这是asterisk ami的协议实现)连接到星号服务器。应用程序在那里启动传出传真。我发现了一些关于我的问题的提示,但我无法找到如何正确处理这个问题。
第一份传真正确发送。
问题是,如果我打电话给 第二次,应用程序保持 挂在主循环中。
我知道我可能不会这样做:
from starpy import manager
from twisted.internet import reactor
def main():
f = manager.AMIFactory(cUser, cPass)
print "Login"
df = f.login(cServer, cPort)
def onLogin(protocol):
print "Logoff again"
df = protocol.logoff()
def onLogoff( result ):
print "Logoff erfolgt"
reactor.stop()
return df.addCallbacks( onLogoff, onLogoff )
def onFailure( reason ):
print "Login failed"
print reason.getTraceback()
df.addCallbacks( onLogin, onFailure )
return df
if __name__ == "__main__":
reactor.callWhenRunning( main )
reactor.run(installSignalHandlers=0)
print "runned the first time"
reactor.callWhenRunning( main )
reactor.run(installSignalHandlers=0)
print "will never reach this point"
我简化了代码 - 它再次没有登录+注销。它永远不会从第二个reactor.run()调用返回。
这是如何正确完成的?我被困在这里 - 提前谢谢。
最诚挚的问候, 弗洛里安。
答案 0 :(得分:9)
正如iny所说,只需拨打一次reactor.run
和reactor.stop
即可完成所有操作。
如果我们考虑您发布的示例代码,我们会看到它采取以下步骤:
如果我们只删除第3步和第4步,那么程序实际上会做一个非常合理的事情。
以下是您实施第3步的方法:
def onLogoff( result ):
print "Logoff erfolgt"
reactor.stop()
这导致第一次调用reactor.run
返回,为您执行第4步扫清了道路:
reactor.callWhenRunning( main )
reactor.run(installSignalHandlers=0)
所以,这里的一般想法是跳到第5步,而不是执行第3步和第4步。考虑如果你重新定义onLogoff
这样会发生什么:
def onLogoff( result ):
print "Logoff erfolgt"
main()
并删除示例的最后三行。这实际上会给你一个无限循环,因为在第二次断开连接后运行相同的onLogoff
并开始第三次连接。但是,您可以使用main
函数的参数来控制重启行为。
一旦这有意义,您可能需要考虑将重试注销从main
函数移出到__main__
块中定义的回调。这是Deferreds功能的重要组成部分:它可以让您在事件源(在本例中为传真发送功能)的实现与处理结果事件的代码(发送第二个传真,或者退出,在这种情况下)。
答案 1 :(得分:3)
您无法重启反应堆。换句话说,您只能调用一次reactor.run()。
相反,它可以在一个反应堆运行中完成所需的一切。
答案 2 :(得分:3)
感谢您的回答,我现在还没有实施解决方案,但我现在知道如何做到这一点......
这是我学到的东西的简短摘要。
首先,简而言之 - 我遇到的扭曲问题:
在我的概念中,我解决了这些问题:
我需要进行大量的重新思考,但只要你明白它就会很容易。
感谢iny和Jean-Paul Calderone的帮助。
答案 3 :(得分:0)
如果您仍在寻找解决方案......我遇到了同样的问题。我有一个脚本使用Twisted来执行远程服务器上的程序。我需要一种从django应用程序中同步运行该脚本的方法。我最终做的是让我的Twisted脚本调用远程服务器,然后打印到stdout。然后从我的Django应用程序中,我通过subprocess.Popen执行该脚本并设置stdout = PIPE,这样我就可以从我的Twisted脚本中捕获输出并在我的Django应用程序中使用它。
这不是很理想,并且几乎违背了Twisted的目的,但这已经超过了“无法再次调用reactor.run(),因为Twisted脚本每次都在它自己的进程中运行
这最终对我很有用,听起来和你所处的情况非常相似。我希望这会有所帮助。祝好运。 (如果您认为它会有所帮助,我可以发布一些代码示例,请告诉我。)