From a2841d8c832c3c90f264071310d37d9c31619fe6 Mon Sep 17 00:00:00 2001 From: tsygankoviva Date: Mon, 22 Jun 2026 16:48:51 +0300 Subject: [PATCH] =?UTF-8?q?websocket-self-flag:=20=D0=B4=D0=BE=D0=B1=D0=B0?= =?UTF-8?q?=D0=B2=D0=B8=D0=BB=20=D1=84=D0=BB=D0=B0=D0=B3=20is=5Fself=20?= =?UTF-8?q?=D0=B2=20=D1=81=D0=BE=D0=BE=D0=B1=D1=89=D0=B5=D0=BD=D0=B8=D1=8F?= =?UTF-8?q?=D1=85=20=D0=B2=D0=B5=D0=B1=D1=81=D0=BE=D0=BA=D0=B5=D1=82=D0=BE?= =?UTF-8?q?=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/src/api/v1/websocket.py | 61 ++++++++++++++++++++++++++----------- 1 file changed, 44 insertions(+), 17 deletions(-) diff --git a/api/src/api/v1/websocket.py b/api/src/api/v1/websocket.py index 274ddff..ffcb9a1 100644 --- a/api/src/api/v1/websocket.py +++ b/api/src/api/v1/websocket.py @@ -1,3 +1,4 @@ +import asyncio from contextlib import asynccontextmanager from dataclasses import asdict import dataclasses @@ -152,7 +153,7 @@ class ConnectionManager: async def broadcast_to_other( self, - message: str, + data: dict, user_id: int, con_key: ConnectionKeyEnum, **kwargs, @@ -162,6 +163,10 @@ class ConnectionManager: if key not in self.connections[con_key]: return + data = data.copy() + data["is_self"] = False + message = dumps(data, default=_convert_error, ensure_ascii=False) + for con_info in self.connections[con_key][key]: if con_info.user_id != user_id: try: @@ -171,20 +176,41 @@ class ConnectionManager: async def broadcast_to_all( self, - message: str, + data: dict, con_key: ConnectionKeyEnum, + user_id: int | None = None, **kwargs, ): key = frozenset(kwargs.items()) if key not in self.connections[con_key]: return + + data = data.copy() + if user_id is None: + data["is_self"] = None + default_message = dumps(data, default=_convert_error, ensure_ascii=False) + self_message = None + else: + data["is_self"] = False + default_message = dumps(data, default=_convert_error, ensure_ascii=False) + data["is_self"] = True + self_message = dumps(data, default=_convert_error, ensure_ascii=False) + for con_info in self.connections[con_key][key]: try: - await con_info.ws.send_text(message) + if user_id is not None and con_info.user_id == user_id: + await con_info.ws.send_text(self_message) + else: + await con_info.ws.send_text(default_message) + + except: pass # Игнорируем недоступные соединения - async def send_back(self, message: str, websocket: WebSocket): + async def send_back(self, data: dict, websocket: WebSocket): + data = data.copy() + data["is_self"] = True + message = dumps(data, default=_convert_error, ensure_ascii=False) await websocket.send_text(message) async def get_data(self, websocket: WebSocket) -> dict: @@ -665,16 +691,16 @@ async def process_websocket( ): data["error"] = "Ячейка уже редактируется другим пользователем" await manager.send_back( - dumps(data, default=_convert_error, ensure_ascii=False), + data, websocket, ) continue await manager.send_back( - dumps(data, default=_convert_error, ensure_ascii=False), + data, websocket, ) await manager.broadcast_to_other( - message=dumps(data, default=_convert_error, ensure_ascii=False), + data=data, user_id=user_id, con_key=con_key, **kwargs_process, @@ -688,11 +714,11 @@ async def process_websocket( form_key=kwargs_process, ) await manager.send_back( - dumps(data, default=_convert_error, ensure_ascii=False), + data, websocket, ) await manager.broadcast_to_other( - message=dumps(data, default=_convert_error, ensure_ascii=False), + data=data, user_id=user_id, con_key=con_key, **kwargs_process, @@ -707,7 +733,7 @@ async def process_websocket( ): data["error"] = "Ячейка уже редактируется другим пользователем" await manager.send_back( - dumps(data, default=_convert_error, ensure_ascii=False), + data, websocket, ) continue @@ -719,7 +745,7 @@ async def process_websocket( ): data["error"] = "Ячейка уже редактируется другим пользователем" await manager.send_back( - dumps(data, default=_convert_error, ensure_ascii=False), + data, websocket, ) continue @@ -733,7 +759,7 @@ async def process_websocket( "Нельзя удалить строку: в этой строке есть редактируемые ячейки" ) await manager.send_back( - dumps(data, default=_convert_error, ensure_ascii=False), + data, websocket, ) continue @@ -762,12 +788,13 @@ async def process_websocket( "row_deleted", ]: await manager.broadcast_to_all( - message=dumps(data, default=_convert_error), + data=data, + user_id=user_id, **kwargs ) else: await manager.broadcast_to_other( - message=dumps(data, default=_convert_error), + data=data, user_id=user_id, **kwargs, ) @@ -775,13 +802,13 @@ async def process_websocket( except BasicAppException as e: data["error"] = e.description or "Неизвестная ошибка" await manager.send_back( - message=dumps(data, default=_convert_error), + data=data, websocket=websocket, ) except IntegrityError as e: data["error"] = str(e) await manager.send_back( - message=dumps(data, default=_convert_error), + data=data, websocket=websocket, ) @@ -791,7 +818,7 @@ async def process_websocket( if tp in handlers: data["error"] = loads((await handlers[tp](request=None, exc=e)).body) await manager.send_back( - message=dumps(data, default=_convert_error), + data=data, websocket=websocket, ) else: