CW server: send out messages in parallel

We now send out messages to all participants at the same time (or more
or less, as asyncio permits). To not fail in case we can't send the
message to one player, we ignore send-exceptions in these occasions and
hope that the `for data in self.websocket` in _handle_client() will
throw an error and kick the client out of our game.
This commit is contained in:
Sebastian Lohff 2025-04-13 20:07:06 +02:00
parent f3732b09d5
commit 5dda7af184
1 changed files with 17 additions and 8 deletions

View File

@ -124,8 +124,7 @@ class Client:
print("FREQ", self.curr_freq, freq, self.freqs)
await self._send(type="join", freq=self.curr_freq, self_id=self.id,
other_players=[c.id for c in self._others(freq)])
for other in self._others(freq):
await other._send(type="player-joined", player=self.id)
await self._send_to_group(self._others(freq), type="player-joined", player=self.id)
async def _handle_morse_state(self, data):
if not self.curr_freq:
@ -136,16 +135,16 @@ class Client:
await self._send_error("No state key with type bool in data")
return
for other in self._others(self.curr_freq):
await other._send(type="morse-state", state=data["state"], from_player=self.id)
await self._send_to_group(self._others(self.curr_freq),
type="morse-state", state=data["state"], from_player=self.id)
async def _leave_room(self):
if not self.curr_freq:
self._send_error("You are not on a frequency")
return
for other in self._others(self.curr_freq):
await other._send(type="player-left", player=self.id)
await self._send_to_group(self._others(self.curr_freq),
type="player-left", player=self.id)
try:
self.freqs[self.curr_freq].remove(self)
except ValueError:
@ -162,10 +161,20 @@ class Client:
def _others(self, freq):
return [c for c in self.freqs[freq] if c.id != self.id]
async def _send(self, **kwargs):
async def _send(self, ignore_exceptions=False, **kwargs):
data = json.dumps(kwargs).encode()
print(f" --> sending out to {self.client}: {data}")
await self.websocket.send(json.dumps(kwargs).encode() + b"\n")
try:
await self.websocket.send(json.dumps(kwargs).encode() + b"\n")
except Exception as e:
print(f"Error sending data to {self.client}: {e}")
if not ignore_exceptions:
raise
async def _send_to_group(self, group, **kwargs):
async with asyncio.TaskGroup() as tg:
for member in group:
tg.create_task(member._send(ignore_exceptions=True, **kwargs))
async def _send_error(self, msg: str):
await self._send(type="error", message=msg)