-
-
Save subzer0iq/8d75d6ef1b0305d82ff14634c430e49d to your computer and use it in GitHub Desktop.
Python asyncio socket server template
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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