2009-12-30 3 views
6

별표 서버에 연결하기 위해 twisted (별표 ami의 프로토콜 구현 인 StarPy)를 사용하고 싶습니다. 응용 프로그램에서 발신 팩스를 시작합니다. 내 문제에 대한 몇 가지 힌트를 찾았지만 올바르게 처리하는 방법을 찾을 수 없습니다.트위스트로 두 번 연결하는 방법 - 올바르게 수행하는 방법?

첫 번째 팩스가 올바르게 발송됩니다.

문제는 내가 두 번째 트위스트 호출하는 경우, 응용 프로그램이 메인 루프에 걸려 을 유지합니다.

나는 내가 여기처럼 이렇게하지 않을 수 있습니다 알고

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() 호출에서 결코 돌아 오지 않을 것입니다.

어떻게 제대로 수행 할 수 있습니까? 나는 여기에 붙어있어 - 미리 감사드립니다.

안녕하십니까, 플로리안.

답변

3

덕분에, 지금 당장 솔루션을 구현하지 않은하지만 난 지금 할 수있는 방법을 알고있다. 짧은

첫째, - 내가 트위스트와 함께했던 문제 :

  1. 나는 트위스트의 비동기 기본을 이해하지 못했다. 나는 GUI 프레임 워크에서 그런 것을 사용했지만 오랫동안 이익을 보지 못했습니다.
  2. 둘째, 이벤트 루프의 동기 호출을 여러 번 생각했습니다. 한 번에 둘 이상의 보내는 팩스 회선을 사용할 수 없기 때문에 이것은 내 마음에 필요했습니다. 꼬인 이벤트 루프는 재시작 할 수 없기 때문에 옵션이 없습니다. 문서에서 "deferToThread"를 읽으면 여기에서 도움이 될 수 있지만 최선의 해결책은 아니라고 생각합니다. 내 개념에서

나는 이러한 문제를 해결 :

나는 많은 생각을 다시해야했지만 최대한 빨리 얻었습니다.

귀하의 도움을 위해 iny 및 Jean-Paul Calderone에게 감사드립니다.

3

원자로를 재시작 할 수 없습니다. 즉, reactor.run()을 한 번만 호출 할 수 있습니다.

대신 하나의 원자로에서 필요한 모든 작업을 수행 할 수 있습니다.

+0

네, 그게 제가 웹에서 찾은 것입니다. 그러나 어떻게 처리해야하는지 알 수 없습니다. 어쩌면 당신은 나를 올바른 방향으로 향하게 할 수 있습니다. * 원자로는 언제 시작해야합니까? 응용 프로그램 시작시 또는 처음 사용할 때? * 하나의 원자로에 1. 연결/2를 요청할 수 있습니까? 팩스 보내기/3. 연결을 두 번 이상 느슨하게합니까? 저는 막혔습니다. 나는 수천 개의 책을 읽고 개발하는데 돈을 투자했다. 나는 대답을 찾지 못했다 ... 미리 감사드립니다. –

+0

죄송합니다. 여기서 내 피드가 작동하지 않았습니다. –

9

iny가 말했듯이 reactor.runreactor.stop을 한 번만 호출하면 모든 작업을 수행해야합니다. 우리는 당신이 게시 된 예제 코드를 고려하면

, 우리는 다음 단계에 소요되는 참조 :

  • 정지에게 원자로를 분리

      는, 원자로
      • 연결을 시작 팩스를 보내
      • 반응기 시작
      • 팩스 연결, 연결 해제
      • 중지 th 전자 우리는 3 단계와 4 단계를 삭제하면 다음 프로그램이 실제로 꽤 합리적인 일을 할 것입니다

    반응.

    reactor.callWhenRunning(main) 
    reactor.run(installSignalHandlers=0) 
    

    그래서, 일반적인 생각 : 4 단계의 구현을위한 길을 삭제,

    def onLogoff(result): 
        print "Logoff erfolgt" 
        reactor.stop() 
    

    reactor.run의 최초의 호출이 반환 원인 : 여기

    은 3 단계를 구현하는 방법은 3 단계와 4 단계 대신 5 단계로 바로 넘어갈 것입니다. onLogoff을 다음과 같이 재정의하면 어떻게 될지 생각하십시오.

    def onLogoff(result): 
        print "Logoff erfolgt" 
        main() 
    

    및 예제의 마지막 세 줄을 삭제하십시오.두 번째 연결 해제 후 동일한 onLogoff이 실행되고 세 번째 연결을 시작하기 때문에 실제로 무한 루프가 발생합니다. 그러나 다시 시작 동작을 제어하기 위해 main 함수에 대한 매개 변수를 사용하여이 문제를 해결할 수 있습니다.

    이 내용이 적합하면 main 기능과 __main__ 블록에 정의 된 콜백으로 재시도 로그 아웃을 이동하는 것이 좋습니다. 이것은 Deferreds의 강점 중 하나입니다. 이벤트 소스 구현 (이 경우 팩스 전송 기능)과 결과 이벤트 처리를위한 코드 (두 번째 팩스 전송 또는 이 경우 종료). 여기

    에게 ... 내가 배운 것들의 짧은 요약을 귀하의 답변

  • +0

    좋아, 나 한테 아이디어주지. 나는 Deferreds 문서를 통해 다시 작업해야합니다. 어쩌면 내 머리가 벽에 부딪히는 것을 막을 수 있습니다. 반응기를 멈추지 않고 나가는 TCP- 연결을 닫는 방법이 있습니까? 나는 TCP-Session을 항상 열어 놓을 생각을 좋아하지 않는다 ... 고마워. –

    0

    아직도 해결책을 찾고 있다면 ... 나는 똑같은 문제가 있습니다. Twisted를 사용하여 원격 서버에서 프로그램을 실행하는 스크립트가 있습니다. 장고 애플리케이션 내에서 동 기적으로 스크립트를 실행하는 방법이 필요했습니다. 내가 한 일은 Twisted 스크립트가 원격 서버를 호출하고 stdout으로 출력하는 것입니다. 그런 다음 내 Django 응용 프로그램 내에서 Subprocess.Popen을 통해 해당 스크립트를 실행하고 표준 출력 = PIPE를 설정하여 Twisted 스크립트의 출력을 캡처하여 장고 응용 프로그램에서 사용할 수있게했습니다.

    이것은 이상적인 것이 아니며 Twisted의 목적을 거의 무효로합니다. 그러나 Twisted 스크립트가 자체 프로세스로 실행되기 때문에 reactor.run()을 두 번째 호출 할 수 없게됩니다. 시간.

    이것은 훌륭한 결과를 얻었으며, 당신이있는 상황과 매우 비슷하게 들린다. 나는 이것이 도움이되기를 바란다. 행운을 빌어. (행운을 빌어. 도움, 그냥 알려주세요).

    +0

    고마워, 나는 이걸 좋아하지 않아. 내가 싫어하는 유일한 점은, (내 구성에서) 연결을 닫은 상태에서 다시 연결될 때까지 대기 상태로 유지한다는 것입니다. 이 디자인이 왜 그런지 이해하지 못합니다. 비동기는 이해할 시간이 필요할지라도 어쨌든 고마워, . –

    +0

    그래서 서브 프로세스가 존재할 때 서브 프로세스를 사용하고 있습니다. 서브 프로세스가 존재하면 연결이 닫힙니다. 내 하위 프로세스를 다시 호출하면 열면 닫히고 닫힙니다. –

    +1

    Twisted로 연결을 끊으려면 언제나'transport.loseConnection()'을 호출 할 수 있습니다. Twisted가 연결을 열어 두는 이유는 그것이 닫히도록 요청하지 않았기 때문입니다! – Glyph

    관련 문제