我有一个使用TTwisted协议的Twisted / Thrift服务器。我希望保持客户端的连接打开,直到发生给定事件(Twisted反应堆通过回调通知我此事件)。
class ServiceHandler(object):
interface.implements(Service.Iface)
def listenForEvent(self):
"""
A method defined in my Thrift interface that should block the Thrift
response until my event of interest occurs.
"""
# I need to somehow return immediately to free up the reactor thread,
# but I don't want the Thrift call to be considered completed. The current
# request needs to be marked as "waiting" somehow.
def handleEvent(self):
"""
A method called when the event of interest occurs. It is a callback method
registered with the Twisted reactor.
"""
# Find all the "waiting" requests and notify them that the event occurred.
# This will cause all of the Thrift requests to complete.
如何在保持阻塞Thrift调用的错觉的同时快速从我的处理程序对象的方法返回?
我从Twisted启动触发器初始化Thrift处理程序:
def on_startup():
handler = ServiceHandler()
processor = Service.Processor(handler)
server = TTwisted.ThriftServerFactory(processor=processor,
iprot_factory=TBinaryProtocol.TBinaryProtocolFactory())
reactor.listenTCP(9160, server)
我的PHP客户端连接:
$socket = new TSocket('localhost', 9160);
$transport = new TFramedTransport($socket);
$protocol = new TBinaryProtocol($transport);
$client = new ServiceClient($protocol);
$transport->open();
$client->listenForEvent();
最后一次调用($client->listenForEvent()
)成功转发到服务器并运行ServiceHandler.listenForEvent
,但即使该服务器方法返回twisted.internet.defer.Deferred()
实例,客户端也会立即收到一个空数组我得到了例外:
异常'TTransportException',消息'TSocket:timed out 从localhost:9160读取4个字节到本地端口38395'
答案 0 :(得分:2)
您应该能够从listenForEvent
返回延期。稍后handleEvent
应该触发返回Deferred(或返回Deferreds)以实际生成响应。
答案 1 :(得分:1)
您看到的错误似乎表明传输没有框架(Twisted需要它以便它可以预先知道每条消息的长度)。此外,Thrift服务器支持从处理程序返回延迟,因此更奇怪。您是否尝试过返回defer.succeed(“某些值”)并查看延迟实际是否有效?然后,您可以转到此处以检查它是否完全有效:
d = defer.Deferred()
reactor.callLater(0, d.callback, results)
return d