python flask web 框架安装 socket.io 模块

文章目录

    想基于 python 的 socket.io 实现实时消息,及在线状态检测。
    同时兼容 rasa 的 socket.io 版本。

    确认 rasa 对应的 socket.io 版本

    > conda list socketio
    (rasa) # packages in environment at ~/miniconda3/envs/rasa:
    
    # Name                    Version                   Build  Channel
    python-socketio           5.8.0                    pypi_0    pypi
    

    这个版本号跟 socket io 的版本对应关系:

    https://github.com/miguelgrinberg/python-socketio

    新建一个 conda 环境

    为了避免破坏 rasa 中的 socket.io 的依赖,担心版本不是完全一样的。

    所以新建一个 conda 的开发环境:

    conda create -n flask --clone base
    

    或者已经有了 flask 的 conda 环境,直接使用:

    conda activate flask
    

    flask socketio 安装

    参考:

    https://flask-socketio.readthedocs.io/en/latest/intro.html

    pip install flask-socketio
    

    Successfully installed bidict-0.22.1 flask-socketio-5.3.6 h11-0.14.0 python-engineio-4.8.2 python-socketio-5.11.0 simple-websocket-1.0.0 wsproto-1.2.0

    flask-socketio==5.3.6

    添加到 requirements.txt 依赖管理文件中。

    flask 代码调整

    from flask import Flask, render_template
    from flask_socketio import SocketIO
    
    app = Flask(__name__)
    app.config['SECRET_KEY'] = 'secret!'
    socketio = SocketIO(app)
    
    
    @app.route("/socketio_test")
    def socketio_test():
        print("socketio html")
        return render_template("socketio_test.html")
    
    
    @socketio.on("message")
    def handle_message(data):
        print("received message: " + data)
    
    
    @socketio.on("json")
    def handle_json(json):
        print("received json: " + str(json))
    
    
    @socketio.on("my event")
    def handle_my_custom_event(json):
        print("my event received json: " + str(json))
    
    
    if __name__ == '__main__':
        socketio.run(app)
    

    注意:

    socketio.run 替换掉了 app.run,但是仍然支持原有的 http 协议。

    模拟客户端测试

    网页端 js 更方便,比用 python 写个 client 程序更直观。

    在上面 flask 的 socketio_test.html 中加入如下 js 代码

    <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.0.1/socket.io.js" integrity="sha512-q/dWJ3kcmjBLU4Qc47E4A9kTB4m3wuTY7vkFJDTZKjTs8jhyGQnaUrxa0Ytd0ssMZhbNua9hE+E7Qv1j+DyZwA==" crossorigin="anonymous"></script>
    <script type="text/javascript" charset="utf-8">
        var socket = io();
        socket.on('connect', function() {
            console.log("socketio connected");
            socket.emit('my event', {data: 'I\'m connected!'});
            socket.emit("hello");
        });
    </script>
    

    测试结果

    实际上,服务端只收到了这条消息:

    my event received json: {'data': "I'm connected!"}
    

    疑问

    • 为何 js 端发送的没指定事件的 hello 消息,server 端接收不到?
    • server 端的 message 监听,为何触发不了?

    关于作者 🌱

    我是来自山东烟台的一名开发者,有感兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊,或者关注我的个人公众号“大象工具”, 查看更多联系方式