1
0
mirror of https://gitlab.com/MoonTestUse1/AdministrationItDepartmens.git synced 2025-08-14 00:25:46 +02:00

add websockets suppor98

This commit is contained in:
MoonTestUse1
2025-01-05 03:01:18 +06:00
parent 9a97764b78
commit 87ee7fbd1a
2 changed files with 73 additions and 56 deletions

View File

@@ -37,8 +37,13 @@ app.include_router(admin.router, prefix="/api/admin", tags=["admin"])
app.include_router(statistics.router, prefix="/api/statistics", tags=["statistics"]) app.include_router(statistics.router, prefix="/api/statistics", tags=["statistics"])
# Добавляем WebSocket маршруты # Добавляем WebSocket маршруты
app.websocket("/api/ws/admin")(notification_manager.admin_endpoint) @app.websocket("/api/ws/admin")
app.websocket("/api/ws/employee/{employee_id}")(notification_manager.employee_endpoint) async def admin_websocket(websocket):
await notification_manager.admin_endpoint(websocket)
@app.websocket("/api/ws/employee/{employee_id}")
async def employee_websocket(websocket, employee_id: int):
await notification_manager.employee_endpoint(websocket, employee_id)
@app.on_event("startup") @app.on_event("startup")
async def startup_event(): async def startup_event():

View File

@@ -1,81 +1,93 @@
"""WebSocket notifications manager"""
from fastapi import WebSocket from fastapi import WebSocket
from typing import Dict, List from typing import Dict, List, Set
import json
import logging import logging
import json
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class NotificationManager: class NotificationManager:
"""Менеджер WebSocket подключений и уведомлений"""
def __init__(self): def __init__(self):
self.active_connections: Dict[str, List[WebSocket]] = { self.admin_connections: Set[WebSocket] = set()
"admin": [], # Подключения админов self.employee_connections: Dict[int, WebSocket] = {}
"employee": [] # Подключения сотрудников
} async def connect(self, websocket: WebSocket, client_type: str, employee_id: int = None):
"""Установка WebSocket соединения"""
async def connect(self, websocket: WebSocket, client_type: str):
await websocket.accept() await websocket.accept()
self.active_connections[client_type].append(websocket) if client_type == "admin":
logger.info(f"New {client_type} connection. Total connections: {len(self.active_connections[client_type])}") self.admin_connections.add(websocket)
logger.info("Admin connected to WebSocket")
elif client_type == "employee" and employee_id:
self.employee_connections[employee_id] = websocket
logger.info(f"Employee {employee_id} connected to WebSocket")
def disconnect(self, websocket: WebSocket, client_type: str): def disconnect(self, websocket: WebSocket, client_type: str, employee_id: int = None):
if websocket in self.active_connections[client_type]: """Закрытие WebSocket соединения"""
self.active_connections[client_type].remove(websocket) if client_type == "admin":
logger.info(f"{client_type} disconnected. Remaining connections: {len(self.active_connections[client_type])}") self.admin_connections.discard(websocket)
logger.info("Admin disconnected from WebSocket")
elif client_type == "employee" and employee_id:
self.employee_connections.pop(employee_id, None)
logger.info(f"Employee {employee_id} disconnected from WebSocket")
async def broadcast_to_admins(self, message: dict): async def broadcast_to_admins(self, message: dict):
"""Отправка сообщения всем подключенным админам""" """Отправка сообщения всем админам"""
logger.info(f"Broadcasting to admins: {message}") disconnected = set()
logger.info(f"Number of admin connections: {len(self.active_connections['admin'])}") for websocket in self.admin_connections:
if not self.active_connections["admin"]:
logger.warning("No admin connections available")
return
disconnected = []
for connection in self.active_connections["admin"]:
try: try:
await connection.send_json(message) await websocket.send_json(message)
logger.info("Message sent successfully to admin")
except Exception as e: except Exception as e:
logger.error(f"Error sending message to admin: {e}") logger.error(f"Error sending message to admin: {e}")
disconnected.append(connection) disconnected.add(websocket)
continue
# Удаляем отключенные соединения # Удаляем отключенные соединения
for connection in disconnected: for websocket in disconnected:
self.disconnect(connection, "admin") self.disconnect(websocket, "admin")
async def broadcast_to_employees(self, employee_id: int, message: dict): async def send_to_employee(self, employee_id: int, message: dict):
"""Отправка сообщения конкретному сотруднику""" """Отправка сообщения конкретному сотруднику"""
logger.info(f"Broadcasting to employee {employee_id}: {message}") websocket = self.employee_connections.get(employee_id)
logger.info(f"Number of employee connections: {len(self.active_connections['employee'])}") if websocket:
if not self.active_connections["employee"]:
logger.warning("No employee connections available")
return
disconnected = []
for connection in self.active_connections["employee"]:
try: try:
await connection.send_json(message) await websocket.send_json(message)
logger.info("Message sent successfully to employee")
except Exception as e: except Exception as e:
logger.error(f"Error sending message to employee: {e}") logger.error(f"Error sending message to employee {employee_id}: {e}")
disconnected.append(connection) self.disconnect(websocket, "employee", employee_id)
continue
# Удаляем отключенные соединения
for connection in disconnected:
self.disconnect(connection, "employee")
async def handle_ping(self, websocket: WebSocket): async def handle_ping(self, websocket: WebSocket):
"""Обработка ping сообщений""" """Обработка ping-сообщений"""
try: try:
await websocket.send_json({"type": "pong"}) await websocket.send_json({"type": "pong"})
logger.debug("Sent pong response")
except Exception as e: except Exception as e:
logger.error(f"Error sending pong: {e}") logger.error(f"Error handling ping: {e}")
async def admin_endpoint(self, websocket: WebSocket):
"""WebSocket endpoint для админов"""
await self.connect(websocket, "admin")
try:
while True:
data = await websocket.receive_json()
if data.get("type") == "ping":
await self.handle_ping(websocket)
except Exception as e:
logger.error(f"Error in admin websocket: {e}")
finally:
self.disconnect(websocket, "admin")
async def employee_endpoint(self, websocket: WebSocket, employee_id: int):
"""WebSocket endpoint для сотрудников"""
await self.connect(websocket, "employee", employee_id)
try:
while True:
data = await websocket.receive_json()
if data.get("type") == "ping":
await self.handle_ping(websocket)
except Exception as e:
logger.error(f"Error in employee websocket: {e}")
finally:
self.disconnect(websocket, "employee", employee_id)
# Создаем глобальный экземпляр менеджера уведомлений
notification_manager = NotificationManager() notification_manager = NotificationManager()