Skip to content

Instantly share code, notes, and snippets.

@johnliu55tw
Last active June 25, 2024 07:53
Show Gist options
  • Save johnliu55tw/38c810c68b09eaa16c521972b79ec125 to your computer and use it in GitHub Desktop.
Save johnliu55tw/38c810c68b09eaa16c521972b79ec125 to your computer and use it in GitHub Desktop.
Python asyncio socket server template
import asyncio
import logging
# XXX: REMOVE THIS LINE IN PRODUCTION!
logging.basicConfig(format='%(asctime)s %(lineno)d %(levelname)s:%(message)s', level=logging.DEBUG)
logger = logging.getLogger(__name__)
# Connected client records
clients = dict()
async def show_tasks():
"""FOR DEBUGGING"""
while True:
await asyncio.sleep(5)
logger.debug(asyncio.Task.all_tasks())
def client_connected_cb(client_reader, client_writer):
# Use peername as client ID
client_id = client_writer.get_extra_info('peername')
logger.info('Client connected: {}'.format(client_id))
# Define the clean up function here
def client_cleanup(fu):
logger.info('Cleaning up client {}'.format(client_id))
try: # Retrievre the result and ignore whatever returned, since it's just cleaning
fu.result()
except Exception as e:
pass
# Remove the client from client records
del clients[client_id]
task = asyncio.ensure_future(client_task(client_reader, client_writer))
task.add_done_callback(client_cleanup)
# Add the client and the task to client records
clients[client_id] = task
async def client_task(reader, writer):
client_addr = writer.get_extra_info('peername')
logger.info('Start echoing back to {}'.format(client_addr))
while True:
data = await reader.read(1024)
if data == b'':
logger.info('Received EOF. Client disconnected.')
return
else:
writer.write(data)
await writer.drain()
if __name__ == '__main__':
host = 'localhost'
port = 9009
loop = asyncio.get_event_loop()
server_coro = asyncio.start_server(client_connected_cb,
host='localhost',
port=9009,
loop=loop)
server = loop.run_until_complete(server_coro)
try:
logger.info('Serving on {}:{}'.format(host, port))
loop.run_forever()
except KeyboardInterrupt as e:
logger.info('Keyboard interrupted. Exit.')
# Close the server
server.close()
loop.run_until_complete(server.wait_closed())
loop.close()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment