如何像生成器一样使用异步协程?

时间:2019-06-13 09:41:17

标签: asynchronous websocket python-3.6 python-asyncio

我想用python开发一种网络套接字观察器,这样当我发送某物时,它应该等到收到响应(有点像阻塞套接字编程),我知道这很奇怪,基本上我想做一个命令行python 3.6工具,可以与服务器通信,同时保持来自用户的所有命令的实时连接。

我可以看到下面的代码段是使用python 3.6的典型代码。

import asyncio
import websockets
import json
import traceback

async def call_api(msg):
   async with websockets.connect('wss://echo.websocket.org') as websocket:
       await websocket.send(msg)
       while websocket.open:
           response = await websocket.recv()
           return (response)

print(asyncio.get_event_loop().run_until_complete(call_api("test 1")))

print(asyncio.get_event_loop().run_until_complete(call_api("test 2")))

但是这将为每个失败的命令创建一个新的ws连接。可能有人说,您必须使用异步处理程序,但我不知道如何将ws响应与命令提示符下的用户输入同步。

我在考虑是否可以使异步协程(call_api)像生成器那样工作,在该生成器中它具有yield语句而不是return,所以我可能可以做些像beow的事情:


async def call_api(msg):
   async with websockets.connect('wss://echo.websocket.org') as websocket:
       await websocket.send(msg)
       while websocket.open:
           response = await websocket.recv()
           msg = yield (response)

generator = call_api("cmd1")

cmd  = input(">>>")

while cmd != 'exit'
    result = next(generator.send(cmd))
    print(result)
    cmd  = input(">>>")


请让我知道您的宝贵意见。

谢谢

1 个答案:

答案 0 :(得分:1)

这可以使用asynchronous generator (PEP 525)来实现。

这是一个有效的示例:

import random
import asyncio


async def accumulate(x=0):
    while True:
        x += yield x
        await asyncio.sleep(1)


async def main():
    # Initialize
    agen = accumulate()
    await agen.asend(None)
    # Accumulate random values
    while True:
        value = random.randrange(5)
        print(await agen.asend(value))


asyncio.run(main())