我有一台扭曲的服务器,实现了LineReceiver协议.
当我响应一个客户端消息而调用sendLine时,它会立即将行写入客户端,就像人们期望的那样.
但是说客户要求服务器进行冗长的计算.我希望服务器定期向客户端发送进度消息.当服务器主动发出请求而客户端没有要求任何东西的情况下调用sendLine时,它似乎在发送任何内容之前等待客户端向服务器发送消息.
如何在不让客户端明确要求的情况下立即将消息从服务器发送到客户端?
解决方法:
如果异步执行计算,请使用deferreds.
反之,如果在单独的线程中进行了较长的计算(例如,以deferrToThread()开始),则使用react.callFromThread()
(我假设我们不在主循环中进行大量计算-这是非常非常错误的:))
小例子:
def some_long_foo(data_array, protocol):
def send_msg(msg, protocol):
# It actually looks petter in classes without pushing protocol here and
# there
protocol.transport.write(msg)
for n, chunk in enumerate(data_array):
do_something_cool(chunk)
if n and (n % 10 == 0):
from twisted.internet import reactor
# here send_msg will be safely executed in main reactor loop
reactor.callFromThread(send_msg, '10 more chunks processed',
protocol)
# Somwhere in lineReceived we start long calculation
def cb(result):
self.transport.write('got result: {}'.format(result))
d = threads.deferToThread(some_long_foo, data_array, self)
d.addCallback(cb)
因此,现在我们将通知客户端每10个数据块处理一次,然后最终将结果发送给客户端.
代码可能有点不正确,例如
UPD:
只是为了澄清:
错过了sendLine部分.通常没关系,称它为transport.write()
标签:twisted,python