2013-08-15 1 views
1

나는 다음과 같이 AMP 클라이언트에서 체인 deferreds에 노력하고 있습니다 :체인 연기 콜백

클라이언트 :

from twisted.internet.endpoints import TCP4ClientEndpoint, connectProtocol 
from twisted.protocols.amp import AMP 

import commands 

def connect_protocol(host, port): 
    destination = TCP4ClientEndpoint(reactor, host, port) 
    d = connectProtocol(destination, AMP()) 

    def connect(protocol): 
     print 'Connecting to server as Mr Spaceman...' 
     return protocol.callRemote(commands.Connect, 
            username='Mr Foo') 

    def say(protocol): 
     print 'Saying "Hello world" to the server...' 
     return protocol.callRemote(commands.Say, 
            phrase='Hello world') 

    d.addCallback(connect) 
    d.addCallback(say) 


def main(host, port): 
    connect_protocol(host, port) 
    print 'Connected to %s:%d...' % (host, port) 
    reactor.run() 

main('127.0.0.1', 12345) 

서버 : 만 connect()는 서버 측에서 해고되고

from twisted.internet.protocol import Factory 
from twisted.protocols.amp import AMP 

import commands 

class CommandProtocol(AMP): 

    def connect(self, username): 
     print "Received connect command: %s." % (username) 
     return {} 
    commands.Connect.responder(connect) 

    def say(self, phrase): 
     print "Received phrase \"%s\"." % phrase 
     return {} 
    commands.Say.responder(say) 

def main(port): 
    factory = Factory() 
    factory.protocol = CommandProtocol 
    reactor.listenTCP(port, factory) 
    print 'Started AMP server on port %d...' % port 
    reactor.run() 

main(12345) 

답변

1

먼저 로깅 사용 :

from sys import stdout 
from twisted.python.log import startLogging 
startLogging(stdout) 

이제 프로그램에서 어떤 일이 벌어지고 있는지보실 수 있습니다.

from twisted.python.log import err 

... 

    d.addCallback(connect) 
    d.addCallback(say) 
    d.addErrback(err, "connect_protocol encountered some problem") 

마지막 지연된 결과가 변경된다

둘째 적어도 그래서 이러한 표시 결정적보다는 가비지 컬렉터에 의존하는 Deferred에 장애가되지 않은 기록 최종 errback을 콜백 및 오류 메시지가 첨부되어 있습니다. 이 경우 say에 전달 된 인수는 connect에 의해 반환 된 Deferred의 결과입니다. 이것은 connect에 대한 인수와 같지 않으므로 callRemote을 사용할 가능성이 없습니다.

이 문제는 여러 가지 방법으로 해결할 수 있습니다.

def connect(protocol): 
    print 'Connecting to server as Mr Spaceman...' 
    d = protocol.callRemote(commands.Connect, username='Mr Foo') 
    d.addCallback(lambda result: (protocol, result)) 
    return d 

def say((protocol, result)): 
    print 'Saying "Hello world" to the server...' 
    return protocol.callRemote(commands.Say, 
           phrase='Hello world') 
+1

'd.addCallback (말) '수행'(최고의 솔루션을하지만 필요는 없다) 최소한의 코드 변경을 수반 한 가지 방법은 connectDeferred의 결과에 별도의 값으로 프로토콜을 전달하는 것입니다 callRemote' 연산을 수행하지만 동일한 클라이언트에서 2 개의 무관 한 호출을 같은 서버로 어떻게 연결합니까 ('connect'와'say')? –