这是我的类中的render_GET函数,它继承自twisted服务器中的resource.Resource:
def render_GET(self, request):
file = request.args['file'][0]
altitude, azimuth, distance = request.args['position'][0].split(",")
self.update_render(file, altitude, azimuth, distance, request.args['clientID'][0])
# update_render() starts a thread that contacts this server again and POSTs data once done
self.add_client(request.args['clientID'][0])
while not self.client_data[request.args['clientID'][0]]:
# I GET STUCK HERE - the thread CANT send data to this dict since server is locked in this loop
time.sleep(0.5)
return "DONE"
我需要扭曲的服务器等到函数update_render
做某事(这个函数是异步的,所以通过调用self.update_render()
我只是启动它,不确定何时写入实际数据。update_render()
的返回数据写在self.client_data dict。
我需要在一个循环中检测这个dict的内容但是我被困在那里 - 似乎服务器被锁定在这个循环中但我需要它来响应其他客户端(它们异步填充self.client_data)
答案 0 :(得分:1)
您永远不想在使用Twisted的应用程序中编写类似于while的循环。
理想情况下,您需要一个比update_render
更好的API - 一个返回延迟的API。 Deferred为您提供统一,可组合,方便的API来管理回调。回调对于使用Twisted编程非常重要。
update_render
获取客户端数据后应使用Deferred
的{{1}}方法,而不是将其放入callback
。通过使用self.client_data
,它在Twisted的事件驱动系统中发挥得很好。您(呼叫者)附加到Deferred
的回叫可以将结果发送给客户端。
Twisted Web有一个小小的怪癖,你需要从Deferred
方法返回twisted.web.server.NOT_DONE_YET
,让服务器知道响应即将到来。
有关异步生成响应的一些示例,请查看Twisted Web In 60 Seconds。