【发布时间】:2012-08-13 19:59:02
【问题描述】:
我有一个服务器,我在其中实现了 NetstringReceiver 协议的子协议。我希望它根据客户端的请求执行异步操作(使用 txredisapi),然后以操作结果进行响应。我的代码的概括:
class MyProtocol(NetstringReceiver):
def stringReceived(self, request):
d = async_function_that_returns_deferred(request)
d.addCallback(self.respond)
# self.sendString(myString)
def respond(self, result_of_async_function):
self.sendString(result_of_async_function)
在上面的代码中,连接到我的服务器的客户端没有得到响应。但是,如果我取消注释,它确实会得到 myString
# self.sendString(myString)
我也知道 result_of_async_function 是一个非空字符串,因为我将它打印到 stdout 。
我该怎么做才能让我用异步函数的结果响应客户端?
更新:可运行的源代码
from twisted.internet import reactor, defer, protocol
from twisted.protocols.basic import NetstringReceiver
from twisted.internet.task import deferLater
def f():
return "RESPONSE"
class MyProtocol(NetstringReceiver):
def stringReceived(self, _):
d = deferLater(reactor, 5, f)
d.addCallback(self.reply)
# self.sendString(str(f())) # Note that this DOES send the string.
def reply(self, response):
self.sendString(str(response)) # Why does this not send the string and how to fix?
class MyFactory(protocol.ServerFactory):
protocol = MyProtocol
def main():
factory = MyFactory()
from twisted.internet import reactor
port = reactor.listenTCP(8888, factory, )
print 'Serving on %s' % port.getHost()
reactor.run()
if __name__ == "__main__":
main()
【问题讨论】:
-
你不应该在某个地方有
reactor.callLater(X, d.callback, ...)吗? -
以上代码只是我认为相关的部分。我有一个使用这个协议的工厂,我调用 reactor.listenTCP(port, factory, )。
-
你能把这个例子填写得更详细些吗?使其完整且可运行?您在这里的想法是正确的,这意味着问题出在细节上,因此为了回答您的问题,我需要查看细节。您可以使用
twisted.internet.task.deferLater模拟异步操作以进行演示。 -
@Glyph,感谢您的意见。我已经编写了说明问题的可运行代码。以防万一我在运行它的方式上做错了什么: 1. 我运行文件:python example.py 2. 在另一个 shell 中:nc localhost 8888 1:a,在这种情况下,我确实收到了来自注释掉的 sendString 但不是来自内部的 sendString 回复(self,response) P.S:抱歉回复晚了,我之前回复过,但刚刚发现 [at]username 功能
标签: python networking asynchronous twisted deferred