Skip to content

Instantly share code, notes, and snippets.

@KrisMelikova
Created April 13, 2023 06:36
Show Gist options
  • Save KrisMelikova/eb8dbe4bfca91b604375ccabdce971b0 to your computer and use it in GitHub Desktop.
Save KrisMelikova/eb8dbe4bfca91b604375ccabdce971b0 to your computer and use it in GitHub Desktop.
A simple echo server with asyncio
import asyncio
from asyncio import AbstractEventLoop
import socket
import logging
import signal
from typing import List
async def echo(connection: socket, loop: AbstractEventLoop) -> None:
try:
while data := await loop.sock_recv(connection, 1024):
print('got data!')
if data == b'boom\r\n':
raise Exception("Неожиданная ошибка сети")
await loop.sock_sendall(connection, data)
except Exception as ex:
logging.exception(ex)
finally:
connection.close()
echo_tasks = []
async def connection_listener(server_socket, loop):
while True:
connection, address = await loop.sock_accept(server_socket)
connection.setblocking(False)
print(f"Получено сообщение от {address}")
echo_task = asyncio.create_task(echo(connection, loop))
echo_tasks.append(echo_task)
class GracefulExit(SystemExit):
pass
def shutdown():
raise GracefulExit()
async def close_echo_tasks(echo_tasks: List[asyncio.Task]):
waiters = [asyncio.wait_for(task, 2) for task in echo_tasks]
for task in waiters:
try:
await task
except asyncio.exceptions.TimeoutError:
# Здесь мы ожидаем истечения тайм-аута
pass
async def main():
server_socket = socket.socket()
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_address = ('127.0.0.1', 8000)
server_socket.setblocking(False)
server_socket.bind(server_address)
server_socket.listen()
for signame in {'SIGINT', 'SIGTERM'}:
loop.add_signal_handler(getattr(signal, signame), shutdown)
await connection_listener(server_socket, loop)
loop = asyncio.new_event_loop()
try:
loop.run_until_complete(main())
except GracefulExit:
loop.run_until_complete(close_echo_tasks(echo_tasks))
finally:
loop.close()
@KrisMelikova
Copy link
Author

Try it:
telnet localhost 8000

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment