我尝试创建一个非阻塞的代码,并允许我创建多个客户端以在服务器上执行某些请求。但是,我不能同时创建多个客户端!
import asyncio
PYTHONASYNCIODEBUG = 1
#ECHO CLIENT PROTOCOL
async def tcp_echo_client(message, loop):
# Send request to server
reader, writer = await asyncio.open_connection('127.0.0.1', 8888, loop=loop)
print('Send: %r' % message)
writer.write(message.encode())
# Receive the information
if message == '1':
await asyncio.Task(read_position(reader))
else:
await asyncio.ensure_future(read_server(reader))
# Close the connection
print('Close the socket')
writer.close()
#ASYNCIO COROUTINES TO REQUEST INFORMATION
async def read_server(reader):
server_message = await reader.read()
print(type(server_message))
print('Received: %r' % server_message.decode())
async def read_position(reader):
while True:
print("I'm Here")
server_message = await reader.read(50)
position = server_message.split()
print(position)
print(type(position))
print('Received: %r' % server_message.decode())
#FUNCTION THAT CREATES THE CLIENT
def main(message):
'''This function creates the client'''
loop = asyncio.get_event_loop()
try:
loop.run_until_complete(tcp_echo_client(message, loop))
finally:
pass
# This is how I create a new client
if __name__ == '__main__':
message = '2'
main(message)
message = '3'
main(message)
我想创建多个客户端,但是,当我发送消息时,代码在第一个主要代码中阻塞(' 1')。如果我使用asyncio,我不知道为什么代码会阻塞。我的服务器接受多个连接,因为如果我单独运行此代码,我可以做任何事情。建议这是每次我点击我的Kivy应用程序的按钮向服务器发送请求时创建客户端。 存在这个问题是因为我想要控制一个机器人并同时做很多事情,但是使用阻止代码我无法做到这一点因为我被卡住了
也许这是一个愚蠢的问题,但我只是在2个月前开始编码,而且我没有任何帮助。
答案 0 :(得分:0)
您的main
函数不会像创建文档字符串一样“创建客户端”。它创建客户端并将其运行至完成。这就是main()
的多次调用导致串行执行的原因。 main()
是一个常规函数,这正是你所期望的,asyncio不会改变它。记住asyncio是单线程的是有用的,所以它不能做一些“在后台运行”魔术,除非你合作。
要合作,你需要告诉aysncio启动两个客户端,然后并行等待它们:
async def main(messages):
loop = asyncio.get_event_loop()
# launch the coroutines in parallel
tasks = [loop.create_task(tcp_echo_client(msg, loop)) for msg in messages]
# don't exit until all of them are done
await asyncio.gather(*tasks)
if __name__ == '__main__':
loop = asyncio.get_event_loop()
loop.run_until_complete(main(['2', '3']))
请注意,在等待你的协同程序时,你不需要将它们包装在asyncio.ensure_future()
或asyncio.Task()
中 - asyncio会自动处理它。 await read_position(reader)
和await read_server(reader)
可以很好地工作,并且具有与较长版本相同的含义。