Each connection used to run its own handler_send loop consuming from the shared dispatcher queue. With zero clients connected (e.g. an iPad that silently drops on sleep), nothing drained the queue, so state updates piled up unbounded and got replayed as a burst on reconnect. Now one pump task drains the queue continuously regardless of connection count, and reconnecting clients resync from global_state instead of a backlog. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TvgC7oy9MxaA4ZQxXqkNdS
33 lines
619 B
Python
33 lines
619 B
Python
import asyncio
|
|
import websockets
|
|
import abc
|
|
|
|
|
|
class WsServer:
|
|
def __init__(self, loop=None):
|
|
self.loop = loop
|
|
|
|
def run_forever(self):
|
|
if self.loop is None:
|
|
asyncio.get_event_loop().run_forever()
|
|
else:
|
|
self.loop.run_forever()
|
|
|
|
async def listen(self, host, port):
|
|
return await websockets.serve(self.handler, host, port)
|
|
|
|
def disconnect(self):
|
|
pass
|
|
|
|
async def handler(self, websocket, path):
|
|
await self.register(websocket)
|
|
try:
|
|
await self.handler_recv(websocket, path)
|
|
finally:
|
|
await self.unregister(websocket)
|
|
|
|
@abc.abstractmethod
|
|
async def handler_recv(self, websocket, path):
|
|
pass
|
|
|