Last active
September 5, 2024 17:04
-
-
Save kracekumar/daf10b3be3191a78b037c0c79667c26c to your computer and use it in GitHub Desktop.
Simple websocket server with uvloop.
This file contains 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
# -*- coding: utf-8 -*- | |
import asyncio | |
import uvloop | |
from aiohttp.web import Application, MsgType, WebSocketResponse | |
def add_socket(app, socket, user_id): | |
if user_id in app['connections']: | |
pass | |
else: | |
print('New connection added {}'.format(user_id)) | |
app['connections'][user_id] = socket | |
async def remove_socket(app, socket, user_id): | |
app['connections'].pop(user_id, None) | |
print('user id: {} is disconnected') | |
await socket.close() | |
async def ws_handler(request): | |
ws = WebSocketResponse() | |
await ws.prepare(request) | |
user_id = request.GET.get('user_id', -1) | |
async for msg in ws: | |
if msg.tp == MsgType.text: | |
if msg.data == 'close': | |
await remove_socket(app=ws.app, socket=ws, user_id=user_id) | |
else: | |
add_socket(app=request.app, socket=ws, user_id=user_id) | |
ws.send_str(msg.data * 2) | |
return ws | |
async def init(loop): | |
app = Application(loop=loop) | |
app['connections'] = {} | |
app.router.add_route('GET', '/', ws_handler) | |
handler = app.make_handler() | |
srv = await loop.create_server(handler, '127.0.0.1', '8000') | |
print("Server running on 127.0.0.1:8000") | |
return app, srv, handler | |
async def cleanup(app, srv, handler): | |
for idx, ws in app['connections'].items(): | |
ws.close() | |
await asyncio.sleep(0.1) | |
srv.close() | |
await handler.finish_connections() | |
await srv.wait_closed() | |
def main(): | |
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy()) | |
loop = asyncio.get_event_loop() | |
app, srv, handler = loop.run_until_complete(init(loop)) | |
try: | |
loop.run_forever() | |
except KeyboardInterrupt: | |
loop.run_until_complete(cleanup(app, srv, handler)) | |
if __name__ == "__main__": | |
main() |
it's realy clean ws example. Solid job.
You can also try this http://sanic.readthedocs.io/en/latest/sanic/routing.html#websocket-routes
Sample benchmark
Good job but it would be more useful if you compare the results with a uvloop-less version.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Sample benchmark