代码之家  ›  专栏  ›  技术社区  ›  JS4137

将render_template()与Flask SocketIO一起使用是否会导致非自动更新?

  •  0
  • JS4137  · 技术社区  · 2 年前

    我最近移植了一个套接字。从Node.js到Python的IO应用程序。我注意到,与Node.js的原始版本不同,Python版本没有在多个连接上自动更新。虽然这个应用程序太复杂了,无法发布一个简单的SO问题,但这里是我的问题的最小复制。

    创建一个名为的文件 templates/index.html :

    <!DOCTYPE html>
    <html lang="en">
        <head>
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <meta http-equiv="X-UA-Compatible" content="ie=edge">
            <script src="https://cdn.socket.io/4.5.4/socket.io.min.js"></script>
            <title>Test chat app - multiple connections</title>
        </head>
        <body>
        <div id="messages"></div>
        <input id="message" type="text" placeholder="Message" />
        <button id="send">Send</button>
        <script>
            let socket = io();
    
            document.getElementById("send").addEventListener("click", () => {
                let msg = document.getElementById("message").value;
                socket.emit("chat", {
                    message: msg
                });
            })
    
            socket.on("update", (messages) => {
                document.getElementById("messages").innerHTML = messages.map((message) => `<p>${message}</p>`).join("")
            });
        </script>
        </body>
    </html>
    

    创建一个名为的文件 test.py :

    from flask import Flask, render_template
    from flask_socketio import SocketIO, send, emit
    
    app = Flask(__name__)
    socketio = SocketIO(app)
    
    messages = []
    
    @app.route("/")
    def main():
        return render_template("index.html")
    
    @socketio.on("connect")
    def handle_connect():
        emit("update", messages)
    
    @socketio.on("chat")
    def handle_chat(data):
        msg = data["message"]
        messages.append(msg)
        emit("update", messages)
    
    if __name__ == "__main__":
        socketio.run(app, port=5500)
    

    现在跑步 python test.py ,并在打开2个选项卡 http://localhost:5500 。如果您尝试在第一个选项卡上发送消息,它们不会显示在第二个选项卡上。

    我怀疑这是由于Flask如何服务于静态资产。这就是问题所在吗?

    0 回复  |  直到 2 年前
        1
  •  0
  •   Detlef    2 年前

    在我看来,你不只是想把你的消息发送回发送者,而是想把它们分发给所有连接的客户端。
    在这种情况下,文档提到 broadcasting

    在启用广播选项的情况下发送消息时,连接到命名空间的所有客户端(包括发送方)都会接收到该消息。当不使用命名空间时,连接到全局命名空间的客户端将接收消息。

    @socketio.on('my event')
    def handle_my_custom_event(data):
        emit('my response', data, broadcast=True)
    
    推荐文章