在 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?
我正在编写命令 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?