Flask 事件处理程序未从 SocketIO 接收事件

Posted

技术标签:

【中文标题】Flask 事件处理程序未从 SocketIO 接收事件【英文标题】:Flask Event Handler not receiving events from SocketIO 【发布时间】:2022-01-23 21:29:37 【问题描述】:

过去几天我一直在开发 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 %

【问题讨论】:

【参考方案1】:

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

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

【讨论】:

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

以上是关于Flask 事件处理程序未从 SocketIO 接收事件的主要内容,如果未能解决你的问题,请参考以下文章

托管在 Heroku 上的 Flask SocketIO 应用程序不使用 @socketio.on 事件?

使用 Flask-SQLAlchemy 事件 API 广播到 Flask-SocketIO?

Flask socketio 不监听事件

Flask-socketio,向另一个命名空间发出事件

使用 pytest 测试 flask-socketio 服务器发出的事件时出错

SocketIO + Flask 检测断开连接