You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

asyncio聊天客户端使用aioconsole的实现难点:input()与asyncio不兼容

异步输入实现方案

以下两种方案均适配最新版asyncio,无需依赖aioconsole:

方案1:Python 3.9+ 原生实现(推荐)

通过asyncio.to_thread将同步input()包装为异步调用,无需额外安装依赖,代码最简:

async def asynchronous_input(prompt: str = "") -> str:
    return await asyncio.to_thread(input, prompt)

方案2:兼容Python 3.7/3.8 版本实现

如果运行环境Python版本低于3.9,使用线程池执行器实现:

import concurrent.futures

# 单例线程池,避免重复创建开销
_input_executor = concurrent.futures.ThreadPoolExecutor(max_workers=1)
async def asynchronous_input(prompt: str = "") -> str:
    loop = asyncio.get_running_loop()
    return await loop.run_in_executor(_input_executor, input, prompt)

原有代码修正

现有代码中存在协程无法并行的问题:chat_client函数内按顺序await message_sender和await message_reciever会导致message_sender的死循环永远阻塞接收逻辑,需要修改为并行运行:

async def chat_client():
    reader, writer = await asyncio.open_connection("xxx.xxx.xxx.xxx", xxx)
    # 同时启动收发两个协程
    await asyncio.gather(
        message_sender(writer),
        message_reciever(reader)
    )

最终message_sender函数修改

替换占位的异步输入调用即可:

async def message_sender(writer):
    try:
        while True:
            # 可自定义输入提示符,比如改成"你: "
            message = await asynchronous_input("")
            await message_writer(message, writer)
    except asyncio.TimeoutError:
        print("----------- You lost your connection -----------")
        writer.close()
        await writer.wait_closed()
        quit()

完整修改后代码示例

import asyncio
import struct
import concurrent.futures

# 兼容全版本的异步输入实现
_input_executor = concurrent.futures.ThreadPoolExecutor(max_workers=1)
async def asynchronous_input(prompt: str = "") -> str:
    loop = asyncio.get_running_loop()
    return await loop.run_in_executor(_input_executor, input, prompt)

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

async def message_sender(writer):
    try:
        while True:
            message = await asynchronous_input("你: ")
            await message_writer(message, writer)
    except asyncio.TimeoutError:
        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(f"\n对方: {rcv_message.decode()}\n你: ", end="")

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

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

内容的提问来源于stack exchange,提问作者SoccerFan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 08:45:02