flask_socketio踩到的坑

需求:

读视频里有人像图片的帧,拿到图片帧,传递给其他同事封装好的算法,获取去隐私后坐标信息。

实现方法:

python服务读取摄像头,拿到摄像头有人像的图片帧,利用flask_socketio推送给前端,进行界面显示。

由于之前也没有用过flask_socketio,这里把踩到的坑,记录一下。
参考博客和flask_socketio文档https://flask-socketio.readthedocs.io/en/latest/intro.html#installation

入坑记录:

第一步安装 pip install flask-socketio 其实这里坑最大,由于依赖的不止这一个包,所以只安装了这一个包后,安装的又是最新版本,服务端启动各种报错,即使安装也没有说明要安装哪个版本的,版本不兼容也是各种意想不到的问题,例如:服务端启动了,代码运行正常了,也可以连接上服务端socket,前端就是接收不到消息。
文档上对应的版本:此截图是flask_socketio文档上的版本要求,一定要遵循这个版本要求,由于版本问题,入坑了3天才出来!
项目用的依赖包:

python服务端依赖包:
flask-socketio            4.0.0
python-socketio           4.0.1
python-engineio           3.2.0
前端依赖包:
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/socket.io/1.3.6/socket.io.min.js"></script>

flask_socketio踩到的坑
项目目录:
flask_socketio踩到的坑
SocketTest.py示例如下:

# -*- coding:utf-8 -*-

from flask import Flask, render_template
from flask_socketio import SocketIO
from threading import Lock
import random
async_mode = None
app = Flask(__name__, static_folder='/', template_folder="/")
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app, cors_allowed_origins="*")  # 允许跨域
thread = None
thread_lock = Lock()


@app.route('/')
def index():
    print('index')
    return render_template('index.html')


# 连接上socket后,需要做的事情 connect为连接的事件,固定这么写
@socketio.on('connect', namespace='/')
def test_connect():
    print('连接上socket服务')
    global thread
    with thread_lock:
        if thread is None:
            print(thread)
            thread = socketio.start_background_task(target=background_thread)
            print('thread is none create')


def callback_a():
    print('service callback success')


def callback_b():
    print('html callback success')


def background_thread():
    while True:
        socketio.sleep(10)
        t = random.randint(1, 100)
        msg = {'data': t}
        print(msg)
        socketio.emit('a', msg,  callback=callback_a())
        print(t)


# 接收到消息做的事情 message为接收消息的事件,如果是接收到的文本,用message,接收json,用json,固定这么写
@socketio.on('message', namespace='/')
def text(message):
    print(message)
    room = 'room1'
    t = random.randint(1, 100)
    msg = 'service-message-' + str(t)
    print(msg)
    socketio.emit('a', {'msg': msg}, callback=callback_b())


if __name__ == '__main__':
    # socketio.run(app, debug=True)
    socketio.run(app, host='0.0.0.0', debug=True, port=5000, log_output=True)


index.html示例如下:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title></title>

    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js" ></script>
    <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/socket.io/1.3.6/socket.io.min.js"></script>
</head>
<body>
<div id="textid"></div>
<script type="text/javascript">
    $(document).ready(function() {
        namespace = '/test_conn';
        console.log(location.protocol)
        console.log(document.domain)
        console.log(location.port)
        console.log(namespace)
        console.log(location.protocol)
        var url = 'ws://127.0.0.61:5000/'
        console.log(url)

        var socket = io.connect(url);

		socket.on('a', function(res) {
		    console.log(res);
            var msg = res.data;
            console.log(msg);
            var res_str = JSON.stringify(res)
            socket.emit('message', 'html receive success');
            document.getElementById("textid").innerHTML = '<p>'+res_str+'</p>';
        });

		console.log("end")


    });
</script>
</body>
</html>

浏览器访问:
http://localhost:5000/index.html
flask_socketio踩到的坑

上一篇:Envoy 基础教程:使用 Unix Domain Socket(UDS) 与上游集群通信


下一篇:flask+socketio+echarts3 服务器监控程序(基于后端数据推送)