""" Gestionnaire WebSocket pour notifications temps réel """ from fastapi import WebSocket from typing import List, Dict, Any import json from datetime import datetime class WebSocketManager: """Gestionnaire de connexions WebSocket""" def __init__(self): """Initialise le gestionnaire""" self.active_connections: List[WebSocket] = [] async def connect(self, websocket: WebSocket): """ Accepte une nouvelle connexion WebSocket Args: websocket: Instance WebSocket """ await websocket.accept() self.active_connections.append(websocket) print(f"[{datetime.now()}] Nouvelle connexion WebSocket. Total: {len(self.active_connections)}") def disconnect(self, websocket: WebSocket): """ Déconnecte un client WebSocket Args: websocket: Instance WebSocket à déconnecter """ if websocket in self.active_connections: self.active_connections.remove(websocket) print(f"[{datetime.now()}] Déconnexion WebSocket. Total: {len(self.active_connections)}") async def send_personal_message(self, message: str, websocket: WebSocket): """ Envoie un message à un client spécifique Args: message: Message à envoyer websocket: Client destinataire """ try: await websocket.send_text(message) except Exception as e: print(f"Erreur envoi message personnel: {e}") async def broadcast(self, message: Dict[str, Any]): """ Diffuse un message à tous les clients connectés Args: message: Dictionnaire du message (sera converti en JSON) """ # Ajouter un timestamp message["timestamp"] = datetime.now().isoformat() json_message = json.dumps(message) # Liste des connexions à supprimer (déconnectées) disconnected = [] for connection in self.active_connections: try: await connection.send_text(json_message) except Exception as e: print(f"Erreur broadcast: {e}") disconnected.append(connection) # Nettoyer les connexions mortes for conn in disconnected: self.disconnect(conn) async def broadcast_scan_start(self): """Notifie le début d'un scan""" await self.broadcast({ "type": "scan_start", "message": "Scan réseau démarré" }) async def broadcast_scan_complete(self, stats: Dict[str, int]): """ Notifie la fin d'un scan avec statistiques Args: stats: Statistiques du scan (total, online, offline, etc.) """ await self.broadcast({ "type": "scan_complete", "message": "Scan réseau terminé", "stats": stats }) async def broadcast_ip_update(self, ip_data: Dict[str, Any]): """ Notifie un changement d'état d'IP Args: ip_data: Données de l'IP mise à jour """ await self.broadcast({ "type": "ip_update", "data": ip_data }) async def broadcast_new_ip(self, ip_data: Dict[str, Any]): """ Notifie la détection d'une nouvelle IP Args: ip_data: Données de la nouvelle IP """ await self.broadcast({ "type": "new_ip", "data": ip_data, "message": f"Nouvelle IP détectée: {ip_data.get('ip')}" }) async def broadcast_scan_progress(self, progress_data: Dict[str, Any]): """ Notifie la progression d'un scan en cours Args: progress_data: Données de progression (current, total, ip) """ await self.broadcast({ "type": "scan_progress", "current": progress_data.get("current"), "total": progress_data.get("total"), "ip": progress_data.get("ip") }) async def broadcast_scan_log(self, message: str): """Diffuse une ligne de log de scan""" await self.broadcast({ "type": "scan_log", "message": message }) # Instance globale du gestionnaire WebSocket ws_manager = WebSocketManager()