LoopingCall AMP命令

时间:2013-08-16 01:57:53

标签: python twisted asynchronous-messaging-protocol

为什么在尝试实现调用AMP命令的LoopingCall函数时会出错?

from twisted.protocols.amp import AMP
from twisted.python.log import startLogging, err
from twisted.internet.task import LoopingCall
from twisted.internet import reactor
from sys import stdout

import commands

startLogging(stdout)


class MyAMP:

    def __init__(self, host, port):
        destination = TCP4ClientEndpoint(reactor, host, port)
        self.protocol = AMP()
        self.d = connectProtocol(destination, self.protocol)

    def say(self):
        return self.protocol.callRemote(commands.Say,
                                   phrase='Hello world')


def loop(myamp):
    myamp.say()


def main(host, port):
    myamp = MyAMP(host, port)
    lc = LoopingCall(loop, myamp=myamp)
    lc.start(4.0)
    reactor.run()

main('127.0.0.1', 12345)

在循环中调用myamp.say()时出错:

2013-08-16 12:28:58-0400 [-] Starting factory <twisted.internet.endpoints.OneShotFactory instance at 0x92273ec>
2013-08-16 12:28:58-0400 [-] Unhandled error in Deferred:
2013-08-16 12:28:58-0400 [-] Unhandled Error
    Traceback (most recent call last):
      File "lib/client.py", line 35, in <module>
        main('127.0.0.1', 12345)
      File "lib/client.py", line 32, in main
        lc.start(4.0)
      File "/usr/local/lib/python2.7/site-packages/twisted/internet/task.py", line 173, in start
        self()
      File "/usr/local/lib/python2.7/site-packages/twisted/internet/task.py", line 218, in __call__
        d = defer.maybeDeferred(self.f, *self.a, **self.kw)
    --- <exception caught here> ---
      File "/usr/local/lib/python2.7/site-packages/twisted/internet/defer.py", line 137, in maybeDeferred
        result = f(*args, **kw)
      File "lib/client.py", line 26, in loop
        myamp.say()
      File "lib/client.py", line 22, in say
        phrase='Hello world')
      File "/usr/local/lib/python2.7/site-packages/twisted/protocols/amp.py", line 821, in callRemote
        return co._doCommand(self)
      File "/usr/local/lib/python2.7/site-packages/twisted/protocols/amp.py", line 1778, in _doCommand
        self.requiresAnswer)
      File "/usr/local/lib/python2.7/site-packages/twisted/protocols/amp.py", line 752, in _sendBoxCommand
        box._sendTo(self.boxSender)
      File "/usr/local/lib/python2.7/site-packages/twisted/protocols/amp.py", line 577, in _sendTo
        proto.sendBox(self)
    exceptions.AttributeError: 'NoneType' object has no attribute 'sendBox'

2013-08-16 12:28:58-0400 [Uninitialized] AMP connection established (HOST:IPv4Address(TCP, '127.0.0.1', 50457) PEER:IPv4Address(TCP, '127.0.0.1', 12345))

2 个答案:

答案 0 :(得分:2)

您在建立连接之前尝试callRemote。默认情况下,LoopingCall会在您启动时立即运行其功能。执行lc.start(4.0)而不是lc.start(4.0, now=False)。这将在第一次通话前等待四秒钟。

答案 1 :(得分:1)

在正常环境中,网络连接稳定,@habnabit的方式将起作用,但在现实世界中,连接延迟无法按预期进行估算。对于这个问题更好的解决方案,必须在放大器客户端连接后执行循环调用。

from twisted.protocols.amp import AMP
from twisted.python.log import startLogging, err
from twisted.internet.task import LoopingCall
from twisted.internet import reactor, endpoints
from sys import stdout

import commands

startLogging(stdout)


class MyAMP:
    def __init__(self, host, port):
        destination = endpoints.TCP4ClientEndpoint(reactor, host, port)
        self.protocol = AMP()
        self.d = endpoints.connectProtocol(destination, self.protocol)


def loop (proto, ) :
    return proto.callRemote(commands.get_user, key='Hello world')

def main(host, port):
    def _cb_connected (proto, ) :
        lc = LoopingCall(loop, proto, )
        lc.start(4.0)
        return

    myamp = MyAMP(host, port)
    myamp.d.addCallback(_cb_connected, )
    reactor.run()

    return

main('127.0.0.1', 12345, )