为什么我的Flask+Flask-SocketIO多房间应用无法匹配正确房间?
问题原因
- 广播通知没有指定房间:调用
socketio.emit时未加room参数,默认会给所有连接的客户端发消息,因此所有房间的用户都会收到加入通知 - 服务端收到消息后没有转发逻辑:
handle_mess函数仅打印了日志,没有执行emit操作,前端无法收到聊天消息 - 前端JS变量名错误:定义的变量是
mes = inp_box.value.trim(),传参时误用了message:mess,变量名不匹配导致消息无法正确发送到后端 - 服务端存在语法小问题:末尾多余闭合大括号,
Style.RESET_ALL是函数需要加()才会生效
修正后的代码
服务端代码
from flask import Flask, render_template, request, redirect, url_for from flask_socketio import SocketIO, join_room from colorama import Fore, Style app = Flask(__name__) socketio = SocketIO(app, cors_allowed_origins="*") @app.route("/") def home(): return render_template("index.html") @app.route("/chat") def chat(): username = request.args.get("username") room = request.args.get("room") if username and room: return render_template("chat.html", username=username, room=room) else: return redirect(url_for("home")) @socketio.on('join_room') def handle_join_room(data): info = "[INFO] "+f"[ROOM: {data['room']}]: "+f"User {data['username']} has joined" print(Fore.CYAN+info) join_room(data['room']) socketio.emit('join_room_ann', data, room=data['room']) Style.RESET_ALL() @socketio.on('send_mess') def handle_mess(data): info = f"[MESSAGE][ROOM: {data['room']}][USER:{data['username']}]: {data['message']}" print(info) socketio.emit('receive_mess', data, room=data['room']) if __name__ == "__main__": socketio.run(app, debug=True)
前端chat.html代码
{% extends "common.html" %} {% block index %} <div class="log left"> <p>Username:</p> <p class="cls">{{username}}</p> <p>Room:</p> <p class="cls">{{room}}</p> </div> <div id="messages" class='bottoml log'> <p>in room:</p> </div> <form action="" id="inp_form"> <div class="log chat"> <div class="in"> <input type="text" id="inp_box" class="chat_in" placeholder="Type your text"> <button type="submit">Send</button> </div> </div> </form> {% endblock %} {% block chat %} <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.2.0/socket.io.js"></script> <script> const socket = io.connect("http://127.0.0.1:5000"); socket.on('connect', function(){ socket.emit("join_room",{ username:"{{username}}", room:"{{room}}" }); let inp_box = document.getElementById('inp_box'); document.getElementById('inp_form').onsubmit = function (e){ e.preventDefault(); let mes = inp_box.value.trim(); if (mes.length){ socket.emit('send_mess', { username:"{{username}}", room:"{{room}}", message:mes }) } inp_box.value=''; inp_box.focus(); } }); socket.on('join_room_ann', function(data){ console.log(data); const newnode = document.createElement('div'); newnode.innerHTML = `${data.username} 加入了房间`; newnode.className+="newn" document.getElementById('messages').appendChild(newnode); }) socket.on('receive_mess', function(data){ const newnode = document.createElement('div'); newnode.innerHTML = `${data.username}: ${data.message}`; document.getElementById('messages').appendChild(newnode); }) </script> {% endblock %}
修改说明
- 所有定向发送的emit调用都添加
room参数,避免全局广播 - 补全服务端消息转发到对应房间的逻辑
- 修正前端变量名拼写错误,保证消息正常发送
- 新增前端接收消息的监听逻辑,用于渲染聊天内容
- 修复服务端语法错误和colorama样式重置不生效的问题
内容的提问来源于stack exchange,提问作者Aadit
相关产品推荐
相关产品推荐

