在 asyncio 聊天客户端中使用 aioconsole 的实现困难 | input() 与 asyncio 不兼容

Implementation difficulties with aioconsole in an asyncio chat client | input() is not compatible with asyncio

我正在编写命令 line/shell 聊天。为了更好地处理输入和输出,我使用了 asyncio。但是 asyncio 不适用于 python 的标准 input() 函数。所以我一直在寻找其他解决方案并遇到了 aioconsole。但是文档很难理解(恕我直言,写得不太好。)所以你能帮我在函数 message_sender() 中实现一个异步输入,方法是替换当前名为 asynchronous_input() 的占位符函数。 (没有 aioconsole 的功能也可以,这正是我遇到的)是的,还有其他关于类似事情的 SO 帖子,但它们都使用非常旧的 asynio 版本。

import asyncio
import struct

async def chat_client():
    reader, writer = await asyncio.open_connection("xxx.xxx.xxx.xxx", xxx)
    await message_sender(writer)
    await message_reciever(reader)

async def message_sender(writer):
    try:
        while True:
            message = await #asynchronous_input()
            await message_writer(message, writer)
    except asyncio.TimeoutError: # Just ignore this exception handler for now, it's only there for later
        print("----------- You lost your connection -----------")
        writer.close()
        await writer.wait_closed()
        quit()

async def message_reciever(reader):
        while True:
            size, = struct.unpack('<L', await reader.readexactly(4)) 
            rcv_message = await reader.readexactly(size)
            print(rcv_message.decode())

async def message_writer(message, writer):
        data = message.encode()
        writer.write(struct.pack('<L', len(data)))
        writer.write(data)
        await writer.drain()

try:
    message = ""
    asyncio.run(chat_client())
except KeyboardInterrupt:
    print("----------- You left the Chat. -----------")
    quit()

如果您只想使用 asyncio

做一次这个准备,它是相当低级的(设置LIMIT例如8192(8K缓冲区)):

loop = asyncio.get_running_loop()
rstream = asyncio.StreamReader(limit=LIMIT, loop=loop)
protocol = asyncio.StreamReaderProtocol(rstream, loop=loop)
await loop.connect_read_pipe(lambda: protocol, sys.stdin)

然后,当您想异步读取一行时:

line = (await rstream.readline()).decode()

您将得到包含换行符的文本行或 EOF 上的空字符串。

但是,直到昨天我才发布了一个相关问题,它的编辑功能确实非常有限。您可能想阅读它,那里推荐了一个专门的图书馆:How to have a comfortable (e.g. GNU-readline style) input line in an asyncio task?