我有一台服务器处于扭曲状态,实现LineReceiver
协议。
当我在响应客户端消息时调用sendLine
时,它会立即将该行写入客户端,正如人们所期望的那样。
但是说客户要求服务器进行冗长的计算。我希望服务器定期向客户端发送进度消息。当服务器主动调用sendLine
而客户端没有要求任何内容时,它似乎等待客户端在发送任何内容之前向服务器发送消息。
如何在没有客户明确要求的情况下立即从服务器向客户端发送消息?
答案 0 :(得分:2)
如果异步执行计算,请使用延迟
其他方式,如果它是在单独的线程中的一些长计算,开始由让我们说deferrToThread(),使用reactor.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()
答案 1 :(得分:1)
您可以随时使用sendLine
发送一行,它应该立即到达,但您可能遇到与服务器阻止相关的问题。
对sendLine
的调用被推迟,因此如果您在一堆处理过程中进行调用,则可能暂时没有执行任何操作,然后当收到消息时,反应器中断处理,接收消息,并在返回处理之前获取排队的消息。您应该在此处阅读其他一些答案,并确保您的处理不会阻塞主线程。
答案 2 :(得分:0)
如果“立即”表示“客户端连接时”,请尝试在sendLine
子类的LineReceiver
中调用connectionMade
。