您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

使用python asyncio.create_server实例提示用户输入

使用python asyncio.create_server实例提示用户输入

您可以使用loop.add_readerSchedule回调在上有可用数据时运行sys.stdin,然后使用asyncio.Queue来将收到的标准输入数据传递给您的data_received方法

import sys
import asyncio


def got_stdin_data(q):
    asyncio.ensure_future(q.put(sys.stdin.readline()))

class EchoServerClientProtocol(asyncio.Protocol):
   def connection_made(self, transport):
       peername = transport.get_extra_info('peername')
       print('Connection from {}'.format(peername))
       self.transport = transport

   def data_received(self, data):
       message = data.decode()
       print('Data received: {!r}'.format(message))
       fut = asyncio.ensure_future(q.get())
       fut.add_done_callback(self.write_reply)

   def write_reply(self, fut):
       reply = fut.result()
       print('Send: {!r}'.format(reply))
       self.transport.write(reply.encode())

       #print('Close the client socket')
       #self.transport.close()

q = asyncio.Queue()
loop = asyncio.get_event_loop()
loop.add_reader(sys.stdin, got_stdin_data, q)
# Each client connection will create a new protocol instance
coro = loop.create_server(EchoServerClientProtocol, '127.0.0.1', 8888)
server = loop.run_until_complete(coro)

# Serve requests until CTRL+c is pressed
print('Serving on {}'.format(server.sockets[0].getsockname()))
try:
    loop.run_forever()
except KeyboardInterrupt:
    pass

# Close the server
server.close()
loop.run_until_complete(server.wait_closed())
loop.close()

唯一棘手的问题是我们如何调用Queue.put/Queue.get方法;它们都是协程,不能yield from在回调或Protocol实例方法中使用。取而代之的是,我们只是使用事件循环来计划它们asyncio.ensure_future,然后使用该add_done_callback方法来处理我们从get()调用中检索到的回复

注意:asyncio.ensure_future是在Python 3.4.4中引入的。在此之前,该方法称为asyncio.async。此外,还引入了Python 3.7asyncio.create_task,它现在是首选方法

python 2022/1/1 18:34:02 有199人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶