refactor: Упрощен метод send - удалены дубликаты

+ Удален query параметр topics
+ Добавлена автоподпись на топик all
This commit is contained in:
AURUMVORXX
2025-11-09 15:00:38 +05:00
parent 304c44ba04
commit f37fded0f7
2 changed files with 36 additions and 62 deletions

View File

@@ -37,7 +37,7 @@ async def call_event(event_name: str, **kwargs):
if result is None: if result is None:
return return
await Server.send( Server.send(
connection = kwargs['connection'], connection = kwargs['connection'],
uuid = kwargs['uuid'], uuid = kwargs['uuid'],
event = 'backend_response', event = 'backend_response',

View File

@@ -36,67 +36,52 @@ class Server:
cls._register_routes(app) cls._register_routes(app)
@classmethod @classmethod
def publish(cls, topic: str, event: str, message: dict) -> asyncio.Future | None: async def _async_send(cls, connection_list: list[WebSocket], data):
try: for connection in connection_list:
if topic not in cls._topics:
raise KeyError('Клиентов прослушивающих этот топик не существует')
# Формируем сообщение
request, data = cls._make_request()
data['event'] = event
data.update(message)
data = json.dumps(data)
# Меняем синтаксис под Squirrel
data = data.replace("'", '\\"').replace('True', 'true').replace('False', 'false')
asyncio.create_task(cls._send_to_topic(topic, data))
return request
except ValueError:
cls._logger.exception('message должен быть типа dict')
@classmethod
async def _send_to_topic(cls, topic, data):
for connection in cls._topics[topic]:
await connection.send_text(data) await connection.send_text(data)
@classmethod @classmethod
async def send(cls, connection: WebSocket, event: str, message: dict, uuid: str | None = None): def send(cls, connection: WebSocket | str | int, event: str, message: dict, uuid: str | None = None):
try: try:
data = { if isinstance(connection, WebSocket):
'event': event, connection_list = [connection]
'uuid': uuid, elif isinstance(connection, int):
} connection_list = cls._registered_clients[connection]
else:
connection_list = cls._topics[connection]
request, data = cls._make_request(event, uuid)
data.update(message) data.update(message)
data = json.dumps(data) except KeyError:
# Меняем синтаксис под Squirrel raise KeyError('Нет зарегистрированного клиента с таким ID')
data = data.replace("'", '\\"').replace('True', 'true').replace('False', 'false')
await connection.send_text(data)
except ValueError: except ValueError:
cls._logger.exception('message должен быть типа dict') raise ValueError('message должен быть типа dict')
@classmethod
def sq_execute(cls, code: str) -> asyncio.Future | None:
if cls._server_connection is None:
return
request, data = cls._make_request()
data['code'] = code
data = json.dumps(data) data = json.dumps(data)
# Меняем синтаксис под Squirrel # Меняем синтаксис под Squirrel
data = data.replace("'", '\\"').replace('True', 'true').replace('False', 'false') data = data.replace("'", '\\"').replace('True', 'true').replace('False', 'false')
asyncio.create_task(cls._async_send(connection_list, data))
asyncio.create_task(cls._server_connection.send_text(data))
return request return request
@classmethod @classmethod
def _make_request(cls): def sq_execute(cls, code: str) -> asyncio.Future:
if cls._server_connection is not None:
return cls.send(cls._server_connection, 'sq_execute', {'code': code})
else:
raise ConnectionError('Сервер не подключен к PyG2O')
@classmethod
def _make_request(cls, event: str, uuid: str | None = None):
if uuid is None:
request_id = str(uuid4()) request_id = str(uuid4())
else:
request_id = uuid
request = asyncio.Future() request = asyncio.Future()
cls._requests[request_id] = request cls._requests[request_id] = request
data = { data = {
'event': event,
'uuid': request_id, 'uuid': request_id,
} }
@@ -105,8 +90,8 @@ class Server:
@classmethod @classmethod
def _register_routes(cls, app): def _register_routes(cls, app):
@app.websocket('/pyg2o') @app.websocket('/pyg2o')
async def pyg2o(websocket: WebSocket, token: str, topics: str | None = None): async def pyg2o(websocket: WebSocket, token: str):
await cls._handle_connection(websocket, token, topics) await cls._handle_connection(websocket, token)
_ = pyg2o _ = pyg2o
@@ -125,13 +110,14 @@ class Server:
cls._topics[topic].discard(connection) cls._topics[topic].discard(connection)
@classmethod @classmethod
async def _handle_connection(cls, connection: WebSocket, token: str, topics: str | None): async def _handle_connection(cls, connection: WebSocket, token: str):
if not await cls._process_query_params(connection, token, topics): if token not in cls._static_tokens and token not in cls._temp_tokens:
await connection.close() await connection.close()
return return
await connection.accept() await connection.accept()
await cls._subscribe(['all'], connection)
cls._logger.info('WebSocket клиент подключился') cls._logger.info('WebSocket клиент подключился')
try: try:
@@ -149,18 +135,6 @@ class Server:
except WebSocketException as e: except WebSocketException as e:
cls._logger.exception(f'Ошибка WebSocket подключения: {e}') cls._logger.exception(f'Ошибка WebSocket подключения: {e}')
@classmethod
async def _process_query_params(cls, connection: WebSocket, token: str, topics: str | None) -> bool:
if token not in cls._static_tokens and token not in cls._temp_tokens:
return False
if topics is not None:
topic_list = [s.strip() for s in topics.split(',')]
await cls._subscribe(topic_list, connection)
return True
@classmethod @classmethod
async def _process_message(cls, connection: WebSocket, message: dict): async def _process_message(cls, connection: WebSocket, message: dict):
match message: match message: