为什么在尝试实现调用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))
答案 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, )