python - 使用 asyncio 同时监听两个 websocket
问题描述
我正在尝试使用 asyncio 同时收听两个 websocket。这行不通。我怎样才能做到这一点?
我想先得到哪个消息,然后打印出来。
async with websockets.connect(sock_uri_1) as w1, \
websockets.connect(sock_uri_2) as w2:
msg1 = ensure_future(w1.recv())
msg2 = ensure_future(w2.recv())
while True:
if msg1.done():
print(msg1.result())
msg1 = ensure_future(w1.recv())
if msg2.done():
print(msg1.result())
msg2 = ensure_future(w2.recv())
time.sleep(1) # Want to avoid this!
解决方案
首先,您应该使用await asyncio.sleep(1)
而不是time.sleep(1)
. asyncio.wait(when_done=FIRST_COMPLETED)
通过使用等待一个(或两个)消息到达,您的方法可以在不休眠的情况下工作:
async with websockets.connect(sock_uri_1) as w1, \
websockets.connect(sock_uri_2) as w2:
msg1 = ensure_future(w1.recv())
msg2 = ensure_future(w2.recv())
while True:
await asyncio.wait([msg1, msg2], when_done=asyncio.FIRST_COMPLETED)
if msg1.done():
print(msg1.result())
msg1 = ensure_future(w1.recv())
if msg2.done():
print(msg1.result())
msg2 = ensure_future(w2.recv())
我发现管理明确的任务有些乏味,尤其是当来源的数量可能不同时。在这种情况下,我将使用队列将消息组合到一个通道中:
async with websockets.connect(sock_uri_1) as w1, \
websockets.connect(sock_uri_2) as w2:
channel = asyncio.Queue()
async def transmit(w, source):
while True:
msg = await w.recv()
await channel.put((source, msg))
asyncio.create_task(transmit(w1, 'source1')
asyncio.create_task(transmit(w2, 'source2')
while True:
source, msg = await channel.get()
if source == 'source1':
print(sock_uri_1, msg)
elif source == 'source2':
print(sock_uri_2, msg)
推荐阅读
- angular - 为什么在正确设置元素时会出错?- TypeError:无法读取 null 的属性“值”
- spring-boot - Spring Boot 禁用 Spring Batch 信息级别日志记录
- java - 由于未检测到导航,已取消页面加载侦听器
- python - 如何在python中链接css文件
- parameters - 如何取出参数中不需要的集合并从一个参数复制到另一个参数
- flutter - 如何使用 Provider 将 ChangeNotifier 范围限定为某些路由?
- google-apps-script - 在 Google 表格中自动添加基于动态单元格的注释
- ssl - Kubernetes 中的 SSL/TLS 证书管理
- image - Tumblr 自己的页面没有从帖子中加载新图片
- linux - 如何从stress-ng --perf 获取CPU 计数器?