initial
This commit is contained in:
0
backend/sockets/__init__.py
Normal file
0
backend/sockets/__init__.py
Normal file
114
backend/sockets/events.py
Normal file
114
backend/sockets/events.py
Normal file
@@ -0,0 +1,114 @@
|
||||
from flask_socketio import emit, join_room, leave_room
|
||||
from backend.app import socketio
|
||||
from backend.auth.middleware import validate_jwt
|
||||
from backend.models import User
|
||||
|
||||
|
||||
@socketio.on('connect')
|
||||
def handle_connect(auth):
|
||||
"""Handle client connection with JWT authentication"""
|
||||
# Extract token from auth parameter
|
||||
token = auth.get('token') if auth else None
|
||||
|
||||
if not token:
|
||||
print('Connection rejected: No token provided')
|
||||
return False # Reject connection
|
||||
|
||||
# Validate JWT
|
||||
claims = validate_jwt(token)
|
||||
if not claims:
|
||||
print('Connection rejected: Invalid token')
|
||||
return False # Reject connection
|
||||
|
||||
# Get user
|
||||
user = User.query.filter_by(authelia_sub=claims['sub']).first()
|
||||
if not user or not user.is_active:
|
||||
print('Connection rejected: User not found or inactive')
|
||||
return False
|
||||
|
||||
print(f'Client connected: {user.email}')
|
||||
emit('connected', {
|
||||
'message': 'Connected to trivia game server',
|
||||
'user': user.to_dict()
|
||||
})
|
||||
|
||||
|
||||
@socketio.on('disconnect')
|
||||
def handle_disconnect():
|
||||
"""Handle client disconnection"""
|
||||
print('Client disconnected')
|
||||
|
||||
|
||||
@socketio.on('join_game')
|
||||
def handle_join_game(data):
|
||||
"""Handle client joining a game room with role validation
|
||||
|
||||
Expected data: { 'game_id': int, 'role': 'contestant' | 'admin', 'token': str }
|
||||
"""
|
||||
game_id = data.get('game_id')
|
||||
role = data.get('role', 'contestant')
|
||||
token = data.get('token')
|
||||
|
||||
if not game_id or not token:
|
||||
emit('error', {'message': 'game_id and token are required'})
|
||||
return
|
||||
|
||||
# Validate JWT
|
||||
claims = validate_jwt(token)
|
||||
if not claims:
|
||||
emit('error', {'message': 'Invalid or expired token'})
|
||||
return
|
||||
|
||||
# Get user
|
||||
user = User.query.filter_by(authelia_sub=claims['sub']).first()
|
||||
if not user or not user.is_active:
|
||||
emit('error', {'message': 'User not found or inactive'})
|
||||
return
|
||||
|
||||
# Join appropriate room based on role
|
||||
if role == 'admin':
|
||||
room = f'game_{game_id}_admin'
|
||||
join_room(room)
|
||||
print(f'User {user.email} joined admin room: {room}')
|
||||
emit('joined', {
|
||||
'game_id': game_id,
|
||||
'room': 'admin',
|
||||
'user': user.to_dict(),
|
||||
'message': f'Joined admin room for game {game_id}'
|
||||
})
|
||||
else:
|
||||
room = f'game_{game_id}_contestant'
|
||||
join_room(room)
|
||||
print(f'User {user.email} joined contestant room: {room}')
|
||||
emit('joined', {
|
||||
'game_id': game_id,
|
||||
'room': 'contestant',
|
||||
'user': user.to_dict(),
|
||||
'message': f'Joined contestant room for game {game_id}'
|
||||
})
|
||||
|
||||
|
||||
@socketio.on('leave_game')
|
||||
def handle_leave_game(data):
|
||||
"""Handle client leaving a game room
|
||||
|
||||
Expected data: { 'game_id': int, 'role': 'contestant' | 'admin' }
|
||||
"""
|
||||
game_id = data.get('game_id')
|
||||
role = data.get('role', 'contestant')
|
||||
|
||||
if not game_id:
|
||||
emit('error', {'message': 'game_id is required'})
|
||||
return
|
||||
|
||||
# Leave appropriate room based on role
|
||||
if role == 'admin':
|
||||
room = f'game_{game_id}_admin'
|
||||
leave_room(room)
|
||||
print(f'Client left admin room: {room}')
|
||||
else:
|
||||
room = f'game_{game_id}_contestant'
|
||||
leave_room(room)
|
||||
print(f'Client left contestant room: {room}')
|
||||
|
||||
emit('left', {'game_id': game_id, 'message': f'Left game {game_id}'})
|
||||
Reference in New Issue
Block a user