【问题标题】:Flask Event Handler not receiving events from SocketIOFlask 事件处理程序未从 SocketIO 接收事件
【发布时间】:2026-01-18 05:40:01
【问题描述】:

过去几天我一直在开发 Flask 聊天应用程序。在尝试添加 SocketIO 时,Flask 控制台显示它正在接收消息,但我的脚本中的事件处理程序没有被执行。

INFO: 71bb17e5b42f4ca18d9e9436d3c42612: Received packet MESSAGE data 2/chat/1,["connected","User has connected!"]
INFO: received event "connected" from 71bb17e5b42f4ca18d9e9436d3c42612 [/chat/1]
INFO: 127.0.0.1 - - [22/Dec/2021 10:11:30] "POST /socket.io/?EIO=3&transport=polling&t=NtYieMW&sid=71bb17e5b42f4ca18d9e9436d3c42612 HTTP/1.1" 200 -
INFO: 71bb17e5b42f4ca18d9e9436d3c42612: Received packet MESSAGE data 2/chat/1,["sentmessage","afeae"]
INFO: received event "sentmessage" from 71bb17e5b42f4ca18d9e9436d3c42612 [/chat/1]
INFO: 127.0.0.1 - - [22/Dec/2021 10:11:31] "POST /socket.io/?EIO=3&transport=polling&t=NtYien3&sid=71bb17e5b42f4ca18d9e9436d3c42612 HTTP/1.1" 200 -

这是烧瓶控制台向我显示的输出。浏览器控制台不输出任何内容。

这里是 app.py

@socketio.on('connected')
def handleConnect():
    print('Someone connected')
    emit('connected')

@socketio.on('sentmessage')
def handleMessage(msg):
    emit('message', msg, broadcast=True)
    print("handling")
    now = datetime.now()
    current_time = now.strftime("%H:%M:%S")
    db.execute(
        "INSERT INTO messages (user, time, chat, message) VALUES (?, ?, ?, ?) ", session["username"], current_time, globalid, msg,
    )

这是 HTML 文件

{% extends "index.html" %}

{% block title %}
{{ chat["name"] }}
{% endblock %}

{% block chat %}
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.3.0/socket.io.js" integrity="sha384-HHKD5G6fqvxz/wBz7BFYeOPzBKELGIZv5l5HAECcXD3zdAS6n8OppmPH9ZxGXY0G" crossorigin="anonymous"></script><script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script type="text/javascript">
    $(document).ready(function() {
    var socket = io.connect('http://127.0.0.1:5000/chat/{{ chat["id"] }}');

    socket.on('connect', function() {
        socket.emit('connected', 'User has connected!');
    });

    socket.on('message', function(msg) {
        var today = new Date();
        var time = today.getHours() + ":" + today.getMinutes() + ":" + today.getSeconds();
        $("#msgsection").append('<div><p><b>{{ user }} - ' + time + '</b></p><p>' + msg + '</p></div>');
        console.log('Received message');
    });

    $('#msgsend').on('click', function() {
        socket.emit('sentmessage', $('#msginput').val());
        $('#msginput').val('');
    });

});
</script>
<div class="chatsection">
    <div class="msgsec" id="msgsection">
        {% for message in messages %}
        <div>
            <p><b>{{ message["user"] }} - {{ message["time"] }}</b></p>
            <p>{{ message["message"] }}</p>
        </div>
        {% endfor %}
    </div>


    <input class="messageinput" id="msginput" autocomplete="off" required autofocus class="form-control" name="message" placeholder="Enter your message here" type="text"/>
    <button class="messageinput" id="msgsend">Send</button>
</div>
{% endblock %}

【问题讨论】:

    标签: javascript python html flask flask-socketio


    【解决方案1】:

    您的客户端正在连接一个名为 /chat/1 的命名空间。您的服务器具有在默认命名空间(称为/)上实现的处理程序。因此,从客户端发送的事件会到达服务器,但不会在任何地方分派,因为您在客户端使用的命名空间上没有处理程序。

    附带说明,Flask-SocketIO 不支持动态命名空间名称,因此您将无法在 /chat/{{ id }} 或类似路径上进行连接。连接 URL 使它看起来好像这是您要连接的 URL,但事实并非如此,命名空间不是实际连接 URL 的一部分。您将需要使用静态命名空间名称(我建议将其保留为默认的 /),然后将聊天 ID 作为参数添加到您的事件负载中。

    【讨论】:

    • 经过进一步研究,我发现了一个叫做“房间”的东西。这适用于我的问题吗?
    • 是的,房间可以动态添加和删除,这样就可以了。