Зачем использовать asyncio Server в качестве диспетчера контекста * и * вызывать serve_forever ()? - PullRequest
2 голосов
/ 03 июня 2019

Документация Python 3.7 для асинхронных потоков включает пример эхо-сервера TCP :

import asyncio

async def handle_echo(reader, writer):
    data = await reader.read(100)
    message = data.decode()
    addr = writer.get_extra_info('peername')

    print(f"Received {message!r} from {addr!r}")

    print(f"Send: {message!r}")
    writer.write(data)
    await writer.drain()

    print("Close the connection")
    writer.close()

async def main():
    server = await asyncio.start_server(
        handle_echo, '127.0.0.1', 8888)

    addr = server.sockets[0].getsockname()
    print(f'Serving on {addr}')

    async with server:
        await server.serve_forever()

asyncio.run(main())

Этот фрагмент мне особенно интересен:

async with server:
    await server.serve_forever()

Итак, мы делаем две вещи:

  • Мы используем asyncio.Server в качестве диспетчера контекста, для которого (с этой страницы) «гарантированно, что объект Serverзакрыто и не принимает новые соединения после завершения асинхронного оператора с оператором ".
  • Мы звоним Server.serve_forever().Обычно начинается прослушивание (если оно еще не запущено) и обеспечивается закрытие сервера при отмене сопрограммы.К тому времени, когда мы достигаем этих строк, мы уже назвали start_server (со значением по умолчанию start_serving=True), поэтому единственный эффект - обеспечение закрытия сервера.

Кажется,как они делают по существу то же самое.Почему обе строки включены в пример?Могут ли наиболее разумные практические применения включать оба?

...