feat; websocket preparation
This commit is contained in:
parent
297c84709d
commit
fa971e1d24
|
@ -3,6 +3,7 @@ from .user_controller import UserController
|
||||||
from .quiz_controller import QuizController
|
from .quiz_controller import QuizController
|
||||||
from .history_controller import HistoryController
|
from .history_controller import HistoryController
|
||||||
from .subject_controller import SubjectController
|
from .subject_controller import SubjectController
|
||||||
|
from .socket_conroller import SocketController
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
"AuthController",
|
"AuthController",
|
||||||
|
@ -10,4 +11,5 @@ __all__ = [
|
||||||
"QuizController",
|
"QuizController",
|
||||||
"HistoryController",
|
"HistoryController",
|
||||||
"SubjectController",
|
"SubjectController",
|
||||||
|
"SocketController",
|
||||||
]
|
]
|
||||||
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
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)
|
27
app/main.py
27
app/main.py
|
@ -1,11 +1,17 @@
|
||||||
|
import eventlet
|
||||||
|
|
||||||
|
eventlet.monkey_patch()
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
|
import logging
|
||||||
|
from flask import Flask, request
|
||||||
|
from flask_socketio import SocketIO
|
||||||
|
|
||||||
sys.path.append(os.path.dirname(__file__))
|
sys.path.append(os.path.dirname(__file__))
|
||||||
|
|
||||||
from di_container import Container
|
from di_container import Container
|
||||||
from configs import Config, LoggerConfig
|
from configs import Config, LoggerConfig
|
||||||
from flask import Flask
|
|
||||||
from blueprints import (
|
from blueprints import (
|
||||||
auth_blueprint,
|
auth_blueprint,
|
||||||
user_blueprint,
|
user_blueprint,
|
||||||
|
@ -13,9 +19,13 @@ from blueprints import (
|
||||||
default_blueprint,
|
default_blueprint,
|
||||||
history_blueprint,
|
history_blueprint,
|
||||||
subject_blueprint,
|
subject_blueprint,
|
||||||
|
socket,
|
||||||
)
|
)
|
||||||
from database import init_db
|
from database import init_db
|
||||||
import logging
|
from controllers import SocketController
|
||||||
|
|
||||||
|
|
||||||
|
socketio = SocketIO(cors_allowed_origins="*")
|
||||||
|
|
||||||
|
|
||||||
def createApp() -> Flask:
|
def createApp() -> Flask:
|
||||||
|
@ -28,13 +38,15 @@ def createApp() -> Flask:
|
||||||
LoggerConfig.init_logger(app)
|
LoggerConfig.init_logger(app)
|
||||||
|
|
||||||
container = Container()
|
container = Container()
|
||||||
|
|
||||||
app.container = container
|
app.container = container
|
||||||
|
|
||||||
mongo = init_db(app)
|
mongo = init_db(app)
|
||||||
if mongo is not None:
|
if mongo is not None:
|
||||||
container.mongo.override(mongo)
|
container.mongo.override(mongo)
|
||||||
|
|
||||||
|
SocketController(socketio)
|
||||||
|
socketio.init_app(app)
|
||||||
|
|
||||||
container.wire(
|
container.wire(
|
||||||
modules=[
|
modules=[
|
||||||
"blueprints.auth",
|
"blueprints.auth",
|
||||||
|
@ -45,7 +57,6 @@ def createApp() -> Flask:
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
# Register Blueprints
|
|
||||||
app.register_blueprint(default_blueprint)
|
app.register_blueprint(default_blueprint)
|
||||||
app.register_blueprint(auth_blueprint, url_prefix="/api")
|
app.register_blueprint(auth_blueprint, url_prefix="/api")
|
||||||
app.register_blueprint(user_blueprint, url_prefix="/api")
|
app.register_blueprint(user_blueprint, url_prefix="/api")
|
||||||
|
@ -53,14 +64,10 @@ def createApp() -> Flask:
|
||||||
app.register_blueprint(history_blueprint, url_prefix="/api/history")
|
app.register_blueprint(history_blueprint, url_prefix="/api/history")
|
||||||
app.register_blueprint(subject_blueprint, url_prefix="/api/subject")
|
app.register_blueprint(subject_blueprint, url_prefix="/api/subject")
|
||||||
|
|
||||||
# for rule in app.url_map.iter_rules():
|
|
||||||
# print(f"Route: {rule} -> Methods: {rule.methods}")
|
|
||||||
|
|
||||||
return app
|
return app
|
||||||
|
|
||||||
|
|
||||||
# app = createApp()
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
app = createApp()
|
app = createApp()
|
||||||
app.run(host="0.0.0.0", debug=Config.DEBUG)
|
|
||||||
|
socketio.run(app, host="0.0.0.0", port=5000, debug=Config.DEBUG)
|
||||||
|
|
Loading…
Reference in New Issue