Spaces:
Running
Running
File size: 3,571 Bytes
16a9a79 22d703d 16a9a79 cda539a |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
import uuid
from flask import Flask, render_template, request
from flask_socketio import SocketIO, join_room, leave_room, emit
app = Flask(__name__)
socketio = SocketIO(app, cors_allowed_origins="*")
# In-memory matchmaking state
PROFILES = {} # sid -> profile dict
WAITING = [] # list of sids waiting
ROOMS = {} # room_id -> (sid1, sid2)
@app.route("/", methods=["GET"])
def index():
return render_template("index.html")
@app.route("/chat", methods=["GET"])
def chat():
return render_template("chat.html")
@socketio.on("find")
def handle_find(profile):
sid = request.sid
PROFILES[sid] = profile
WAITING.append(sid)
emit("status", {"msg": "Finding partner..."}, room=sid)
try_match()
@socketio.on("disconnect")
def handle_disconnect(sid):
# `sid` is passed in by Socket.IO on disconnect
if sid in WAITING:
WAITING.remove(sid)
PROFILES.pop(sid, None)
# Remove from any room
for room, pair in list(ROOMS.items()):
if sid in pair:
other = pair[1] if pair[0] == sid else pair[0]
emit("status", {"msg": "Partner left."}, room=other)
leave_room(room, sid=other)
ROOMS.pop(room)
@socketio.on("subscribe")
def handle_subscribe(data):
room = data.get("room")
sid = request.sid
if room in ROOMS and sid in ROOMS[room]:
join_room(room)
emit("status", {"msg": f"Joined room {room}!"}, room=sid)
else:
emit("status", {"msg": "Invalid room or not in this room."}, room=sid)
@socketio.on("chat")
def handle_chat(data):
room = data.get("room")
msg = data.get("msg")
if room in ROOMS:
emit("chat", {"msg": msg}, room=room)
@socketio.on("leave")
def handle_leave(data):
room = data.get("room")
sid = request.sid
emit("left", {}, room=sid)
if room in ROOMS:
other = next(s for s in ROOMS[room] if s != sid)
emit("status", {"msg": "Partner left."}, room=other)
leave_room(room, sid=other)
ROOMS.pop(room)
def try_match():
import random
random.shuffle(WAITING) # To ensure fairness
used = set()
pairs = []
for i, sid1 in enumerate(WAITING):
if sid1 in used: continue
p1 = PROFILES.get(sid1)
if not p1: continue
for j in range(i + 1, len(WAITING)):
sid2 = WAITING[j]
if sid2 in used: continue
p2 = PROFILES.get(sid2)
if not p2: continue
# Gender filtering
if p1['looking'] != 'any' and p2['gender'].lower() != p1['looking'].lower():
continue
if p2['looking'] != 'any' and p1['gender'].lower() != p2['looking'].lower():
continue
# Interests matching
if set(p1['interests']) & set(p2['interests']):
pairs.append((sid1, sid2))
used.add(sid1)
used.add(sid2)
break
# Remove matched from waiting, make rooms
for sid1, sid2 in pairs:
for sid in (sid1, sid2):
if sid in WAITING:
WAITING.remove(sid)
room = str(uuid.uuid4())
ROOMS[room] = (sid1, sid2)
join_room(room, sid=sid1)
join_room(room, sid=sid2)
emit("matched", {"room": room}, room=sid1)
emit("matched", {"room": room}, room=sid2)
if __name__ == "__main__":
socketio.run(app, host="0.0.0.0", port=7860) |