195 lines
7.6 KiB
Python
195 lines
7.6 KiB
Python
![]() |
#!/usr/bin/env python3
|
||
|
"""
|
||
|
Configuration uWSGI pour l'intégration des WebSockets avec OEDB
|
||
|
"""
|
||
|
|
||
|
import os
|
||
|
import sys
|
||
|
import json
|
||
|
import time
|
||
|
import asyncio
|
||
|
from oedb.utils.logging import logger
|
||
|
|
||
|
# Import l'application Falcon principale
|
||
|
sys.path.insert(0, os.path.dirname(__file__))
|
||
|
from backend import app
|
||
|
|
||
|
# Import le gestionnaire WebSocket
|
||
|
from oedb.resources.demo.websocket import WebSocketManager
|
||
|
|
||
|
# Créer une instance du gestionnaire WebSocket
|
||
|
ws_manager = WebSocketManager()
|
||
|
|
||
|
# Gestionnaire de WebSocket pour uWSGI
|
||
|
def websocket_handler(environ, start_response):
|
||
|
"""Gestionnaire pour les connexions WebSocket."""
|
||
|
path = environ.get('PATH_INFO', '')
|
||
|
|
||
|
# Vérifier si c'est une requête WebSocket et qu'elle est sur le bon chemin
|
||
|
if path == '/ws' and environ.get('HTTP_UPGRADE', '').lower() == 'websocket':
|
||
|
try:
|
||
|
# Importer uwsgi ici car il n'est disponible qu'à l'exécution dans l'environnement uWSGI
|
||
|
import uwsgi
|
||
|
|
||
|
# Passer la requête au gestionnaire de WebSocket uWSGI
|
||
|
uwsgi.websocket_handshake()
|
||
|
logger.info(f"Nouvelle connexion WebSocket établie")
|
||
|
|
||
|
client_id = id(environ)
|
||
|
# Simuler la fonction handle_connection pour ce client
|
||
|
try:
|
||
|
# Ajouter le client à la liste
|
||
|
with ws_manager.lock:
|
||
|
ws_manager.clients[client_id] = {
|
||
|
'websocket': environ, # Utiliser environ comme proxy
|
||
|
'username': None,
|
||
|
'position': None,
|
||
|
'last_seen': time.time(),
|
||
|
'show_only_to_friends': False,
|
||
|
}
|
||
|
|
||
|
# Envoyer la liste des utilisateurs connectés
|
||
|
users_list = []
|
||
|
with ws_manager.lock:
|
||
|
for client_info in ws_manager.clients.values():
|
||
|
if client_info.get('username'):
|
||
|
users_list.append({
|
||
|
'username': client_info['username'],
|
||
|
'timestamp': time.time()
|
||
|
})
|
||
|
|
||
|
# Envoyer la liste des utilisateurs
|
||
|
uwsgi.websocket_send(json.dumps({
|
||
|
'type': 'users',
|
||
|
'users': users_list
|
||
|
}).encode('utf-8'))
|
||
|
|
||
|
# Boucle de traitement des messages
|
||
|
while True:
|
||
|
msg = uwsgi.websocket_recv()
|
||
|
data = json.loads(msg.decode('utf-8'))
|
||
|
message_type = data.get('type')
|
||
|
|
||
|
if message_type == 'position':
|
||
|
# Traiter la mise à jour de position
|
||
|
username = data.get('username')
|
||
|
position = data.get('position')
|
||
|
timestamp = data.get('timestamp')
|
||
|
show_only_to_friends = data.get('showOnlyToFriends', False)
|
||
|
|
||
|
# Mettre à jour les informations du client
|
||
|
with ws_manager.lock:
|
||
|
if client_id in ws_manager.clients:
|
||
|
ws_manager.clients[client_id]['username'] = username
|
||
|
ws_manager.clients[client_id]['position'] = position
|
||
|
ws_manager.clients[client_id]['last_seen'] = time.time()
|
||
|
ws_manager.clients[client_id]['show_only_to_friends'] = show_only_to_friends
|
||
|
|
||
|
# Mettre à jour dans le dictionnaire des positions
|
||
|
ws_manager.positions[username] = {
|
||
|
'position': position,
|
||
|
'timestamp': timestamp,
|
||
|
'show_only_to_friends': show_only_to_friends
|
||
|
}
|
||
|
|
||
|
# Diffuser à tous les autres clients
|
||
|
broadcast_position(username, position, timestamp, show_only_to_friends)
|
||
|
|
||
|
elif message_type in ['pouet', 'friendRequest']:
|
||
|
# Rediriger ces messages vers les destinataires
|
||
|
handle_direct_message(data, message_type)
|
||
|
|
||
|
except Exception as e:
|
||
|
logger.error(f"Erreur WebSocket: {e}")
|
||
|
finally:
|
||
|
# Supprimer le client de la liste
|
||
|
with ws_manager.lock:
|
||
|
if client_id in ws_manager.clients:
|
||
|
username = ws_manager.clients[client_id].get('username')
|
||
|
if username and username in ws_manager.positions:
|
||
|
del ws_manager.positions[username]
|
||
|
del ws_manager.clients[client_id]
|
||
|
|
||
|
except Exception as e:
|
||
|
logger.error(f"Erreur de connexion WebSocket: {e}")
|
||
|
return ['500 Internal Server Error', [], [b'WebSocket Error']]
|
||
|
|
||
|
# Si ce n'est pas une requête WebSocket, passer à l'application WSGI
|
||
|
return app(environ, start_response)
|
||
|
|
||
|
# Fonctions utilitaires pour les WebSockets uWSGI
|
||
|
def broadcast_position(username, position, timestamp, show_only_to_friends):
|
||
|
"""Diffuse la position d'un utilisateur à tous les autres utilisateurs."""
|
||
|
import uwsgi
|
||
|
|
||
|
message = json.dumps({
|
||
|
'type': 'position',
|
||
|
'username': username,
|
||
|
'position': position,
|
||
|
'timestamp': timestamp,
|
||
|
'showOnlyToFriends': show_only_to_friends
|
||
|
}).encode('utf-8')
|
||
|
|
||
|
with ws_manager.lock:
|
||
|
for client_id, client_info in ws_manager.clients.items():
|
||
|
# Ne pas envoyer à l'utilisateur lui-même
|
||
|
if client_info.get('username') == username:
|
||
|
continue
|
||
|
|
||
|
try:
|
||
|
# Dans uWSGI, nous devons utiliser environ pour identifier le socket
|
||
|
if 'websocket' in client_info:
|
||
|
uwsgi.websocket_send(message)
|
||
|
except Exception as e:
|
||
|
logger.error(f"Erreur d'envoi de broadcast de position: {e}")
|
||
|
|
||
|
def handle_direct_message(data, message_type):
|
||
|
"""Traite un message direct (pouet ou demande d'ami)."""
|
||
|
import uwsgi
|
||
|
|
||
|
from_user = data.get('from')
|
||
|
to_user = data.get('to')
|
||
|
|
||
|
if not from_user or not to_user:
|
||
|
return
|
||
|
|
||
|
# Trouver le client destinataire
|
||
|
recipient_client_id = None
|
||
|
with ws_manager.lock:
|
||
|
for client_id, client_info in ws_manager.clients.items():
|
||
|
if client_info.get('username') == to_user:
|
||
|
recipient_client_id = client_id
|
||
|
break
|
||
|
|
||
|
if recipient_client_id and recipient_client_id in ws_manager.clients:
|
||
|
# Préparer le message selon le type
|
||
|
if message_type == 'pouet':
|
||
|
msg = json.dumps({
|
||
|
'type': 'pouet',
|
||
|
'from': from_user,
|
||
|
'timestamp': data.get('timestamp')
|
||
|
}).encode('utf-8')
|
||
|
logger.info(f"Pouet pouet envoyé de {from_user} à {to_user}")
|
||
|
elif message_type == 'friendRequest':
|
||
|
msg = json.dumps({
|
||
|
'type': 'friendRequest',
|
||
|
'from': from_user,
|
||
|
'timestamp': data.get('timestamp')
|
||
|
}).encode('utf-8')
|
||
|
logger.info(f"Demande d'ami envoyée de {from_user} à {to_user}")
|
||
|
|
||
|
# Envoyer le message
|
||
|
try:
|
||
|
uwsgi.websocket_send(msg)
|
||
|
except Exception as e:
|
||
|
logger.error(f"Erreur d'envoi de message direct: {e}")
|
||
|
|
||
|
# Appliquer le patch au démarrage
|
||
|
patch_websocket_manager()
|
||
|
|
||
|
# Application WSGI pour uWSGI
|
||
|
application = websocket_handler
|
||
|
|
||
|
# Remarque: Pour utiliser ce fichier, démarrez uWSGI avec:
|
||
|
# uwsgi --http :8080 --http-websockets --wsgi-file wsgi_websocket.py --async 100 --ugreen
|