from flask_socketio import SocketIO, emit, join_room, leave_room from flask import request class SocketController: def __init__(self, socketio: SocketIO): self.socketio = socketio self.rooms = {} # room_name -> set of sids self._register_events() def _register_events(self): @self.socketio.on("connect") def on_connect(): print(f"Client connected: {request.sid}") emit("connection_response", {"status": "connected", "sid": request.sid}) @self.socketio.on("disconnect") def on_disconnect(): sid = request.sid # Remove user from all rooms they joined for room, members in self.rooms.items(): if sid in members: members.remove(sid) emit( "room_message", {"message": f"A user has disconnected.", "room": room}, room=room, ) print(f"Client disconnected: {sid}") @self.socketio.on("join_room") def handle_join_room(data): if not isinstance(data, dict): emit("error", {"message": "Invalid data format"}) return room = data.get("room") username = data.get("username", "anonymous") sid = request.sid # Create room if it doesn't exist if room not in self.rooms: self.rooms[room] = set() # Check if room has space if len(self.rooms[room]) >= 2: emit("room_full", {"message": "Room is full. Max 2 users allowed."}) return # Join room self.rooms[room].add(sid) join_room(room) emit( "room_message", {"message": f"{username} has joined the room.", "room": room}, room=room, ) @self.socketio.on("leave_room") def handle_leave_room(data): room = data.get("room") username = data.get("username", "anonymous") sid = request.sid if room in self.rooms and sid in self.rooms[room]: self.rooms[room].remove(sid) leave_room(room) print(f"{username} left room {room}") emit( "room_message", {"message": f"{username} has left the room.", "room": room}, room=room, ) @self.socketio.on("send_message") def on_send_message(data): room = data.get("room") message = data.get("message") username = data.get("username", "anonymous") print(f"[{room}] {username}: {message}") emit("receive_message", {"message": message, "from": username}, room=room)