我正在使用 Python 3.6、asyncio 和 websockets图书馆。我正在尝试为基于 websocket 的服务构建一个客户端,其工作原理如下:
客户端可以使用自定义id
、方法
和一些params
发送JSON请求。该服务将回复 JSON 有效负载,并回显相同的 id
和 data
作为方法调用的结果。
我希望在此设备之上有一个抽象,其工作原理如下:
wsc = get_websocket_connection()
async def call_method(method, **params):
packet = make_json_packet(method, params)
await wsc.send(packet)
resp = await wsc.recv()
return decode_json_packet(resp)
async def working_code():
separate_request = asyncio.ensure_future(call_method("quux"))
first_result = await call_method("foo", x=1)
second_result = await call_method("bar", y=first_result)
print(second_result)
return await separate_request
现在,我希望 separate_request
在处理 first_result
和 second_result
时异步等待。但我不能保证 wsc.recv() 调用会返回匹配的响应;事实上,我不能保证服务会按请求的顺序返回响应。
我可以使用 id
字段来消除响应的歧义。但是我如何编写 call_method()
以便它在内部管理请求并在收到相应回复时恢复“正确的”协程?
最佳答案
当我做过这类事情之前,我倾向于将事情分成两部分:
- “发送代码”(可以是多个线程),这设置了响应应该发送到的位置(即
dict
的id
到函数或Future
s),然后发送请求并阻止响应 - “接收代码”(可能每个套接字一个线程),监视所有入站流量并将响应传递给对
id
感兴趣的任何代码。 。这也是处理意外关闭的套接字的明智位置,这应该适本地推出异常
这可能是几百行代码并且非常特定于应用程序......
关于python - 异步: multiplexing messages over single websocket connection,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54256630/