连接两次扭曲 - 如何正确地做到这一点?

Flo*_*agg 6 twisted

我想使用twisted(和StarPy这是asterisk ami的协议实现)连接到星号服务器.应用程序在那里启动传出传真.我发现了一些关于我的问题的提示,但我无法找到如何正确处理这个问题.

第一个传真正确发送出去.

问题是,如果我第二次调用twisted,应用程序将继续挂在主循环中.

我知道我可能不会这样做:

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"
Run Code Online (Sandbox Code Playgroud)

我简化了代码 - 它再次没有登录+注销.它永远不会从第二个reactor.run()调用返回.

这是如何正确完成的?我被困在这里 - 提前谢谢.

最诚挚的问候,弗洛里安.

Jea*_*one 9

作为INY说,你需要做的一切只有一个调用reactor.runreactor.stop.

如果我们考虑您发布的示例代码,我们会看到它采取以下步骤:

  1. 启动反应堆
    • 连接,发送传真,断开连接
    • 停止反应堆
    • 启动反应堆
    • 连接,发送传真,断开连接
    • 停止反应堆

如果我们只删除第3步和第4步,那么程序实际上会做一个非常合理的事情.

以下是您实施第3步的方法:

def onLogoff( result ):
    print "Logoff erfolgt"
    reactor.stop()
Run Code Online (Sandbox Code Playgroud)

这导致第一次调用reactor.run返回,为您执行第4步扫清了道路:

reactor.callWhenRunning( main )
reactor.run(installSignalHandlers=0)
Run Code Online (Sandbox Code Playgroud)

因此,这里的一般想法是跳到第5步,而不是执行第3步和第4步.考虑如果重新定义onLogoff这样可能会发生什么:

def onLogoff( result ):
    print "Logoff erfolgt"
    main()
Run Code Online (Sandbox Code Playgroud)

并删除示例的最后三行.这实际上会给你一个无限循环,因为onLogoff它在第二次断开后运行并启动第三次连接.但是,您可以使用main函数的参数来解决此问题,以控制重新启动行为.

一旦这有意义,您可能需要考虑将重试注销移出main函数并进入__main__块中定义的回调.这是Deferreds功能的重要组成部分:它可以让您在事件源(在本例中为传真发送功能)的实现与处理结果事件的代码(发送第二个传真,或者退出,在这种情况下).


Flo*_*agg 3

感谢您的回答,我现在还没有实施解决方案,但我知道现在该怎么做......

这是我学到的东西的简短总结。

首先,简而言之 - 我在扭曲方面遇到的问题:

  1. 我不明白twisted的异步基础知识。我在图形用户界面框架中使用了类似的东西,但很长一段时间没有看到好处。
  2. 其次,我尝试考虑多次同步调用事件循环。在我看来,这是必要的,因为我一次不能使用多于一根传出传真线路。因为twisted的事件循环是不可重启的,所以这是没有选择的。正如我在文档中读到的那样,“deferToThread”可以在这里帮助我,但我认为这不是最好的解决方案。

在我的概念中,我解决了这些问题:

我需要大量的重新思考,但一旦你明白了,它看起来就很容易了。

感谢 iny 和 Jean-Paul Calderone 的帮助。