对Flask-SocketIO运作机制的一点理解

对Flask-SocketIO运作机制的一点理解


在这里插入图片描述

代码框架

后端

from flask import Flask, render_template
from flask_socketio import SocketIO, emit

app = Flask(__name__, template_folder='./project_frontend/template')
app.config['SECRET_KEY'] = 'secret_key'

socketio = SocketIO()
socketio.init_app(app, cors_allowed_origins='*')

# 定义连接空间,一个连接空间中包含多个事件
webUser = "/webUser"
device = "/device"

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

@app.route('/webUser')
def push_once():
    return render_template('webUser.html')

# 定义webUser空间中的事件
@socketio.on('connect', namespace=webUser)
def connected_msg():
    print('webUser connected.')
@socketio.on('disconnect', namespace=webUser)
def disconnect_msg():
    print('webUser disconnected.')
@socketio.on('webUserEvent', namespace=webUser)
def web_msg(control_data):
    print(control_data)
    socketio.emit('control_stream', control_data, broadcast=False, namespace=device)

# 定义device空间中的事件
@socketio.on('connect', namespace=device)
def connected_msg():
    print('device connected.')
@socketio.on('disconnect', namespace=device)
def disconnect_msg():
    print('device disconnected.')
@socketio.on('deviceEvent', namespace=device)
def web_msg(sensor_data):
    print(sensor_data)
    socketio.emit('sense_stream', sensor_data, broadcast=False, namespace=webUser)

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

前端
webUser

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>SocketIO Demo by star_melon</title>
    <script type="text/javascript" src="//cdn.bootcss.com/jquery/3.1.1/jquery.min.js"></script>
    <script type="text/javascript" src="//cdn.bootcdn.net/ajax/libs/socket.io/3.1.2/socket.io.min.js"></script>
</head>

<body>

    <h2>SocketIO Demo by star_melon</h2>
    <div>senserVal:<div id="senserVal">--</div>
    </div>


    <input type="range" min="0" max="1023" step="1" oninput="callback(this.value)" onchange="callback(this.value)"
        id="lightintense">
    <script>

        // 定义连接空间webUser,一个连接空间中包含多个事件
        namespace = '/webUser';
        var socket = io.connect(location.protocol + '//' + document.domain + ':' + location.port + namespace);

        //  发送事件
        function callback(control_data) {
            socket.emit('webUserEvent', control_data);
        }

        $(document).ready(function () {

            // 监听事件,sense_stream为事件id
            socket.on('sense_stream', function (sensor_data) {
                if (sensor_data) {
                    $("#senserVal").text(sensor_data);
                }
            })

        });

    </script>
</body>

</html>

device

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>SocketIO Demo by star_melon</title>
    <script type="text/javascript" src="//cdn.bootcss.com/jquery/3.1.1/jquery.min.js"></script>
    <script type="text/javascript" src="//cdn.bootcdn.net/ajax/libs/socket.io/3.1.2/socket.io.min.js"></script>
</head>

<body>

    <h2>SocketIO Demo by star_melon</h2>
    <div>lightintense: <div id="ledIntense">--</div>
    </div>

    <script>
        
        // 定义连接空间device,一个连接空间中包含多个事件
        namespace = '/device';
        var socket = io.connect(location.protocol + '//' + document.domain + ':' + location.port + namespace);
        
        $(document).ready(function () {
            
            // 主动发送事件
            var cnt = 0;
            window.setInterval(sensorSend, 1000);
            function sensorSend() {
                socket.emit('deviceEvent', ++cnt);
            }
            
            // 监听事件,control_stream为事件id
            socket.on('control_stream', function (control_data) {
                if (control_data) {
                    $("#ledIntense").text(control_data);
                }
            });

        });
    </script>
</body>

</html>

如何理解

在后端可以定义多个连接空间,每个空间里又可以定义多个监听事件,连接空间相当于对服务进行大类的区分,在大类里面就有不同的事件,由此建立一对一,一对多,多对多的通信模式。

  • 如在后端定义webUser空间和device空间
webUser = "/webUser"
device = "/device"
  • 然后每个空间分别包含3个事件,只需要在定义事件时指明其属于哪个空间即可
@socketio.on('connect', namespace=webUser)
@socketio.on('disconnect', namespace=webUser)
@socketio.on('webUserEvent', namespace=webUser)
  • 前端建立连接时指定连接空间、发送时指定事件即可,control_data传到后端webUserEvent事件
namespace = '/webUser';
        var socket = io.connect(location.protocol + '//' + document.domain + ':' + location.port + namespace);
        socket.emit('webUserEvent', control_data);
  • 如在前端定义监听事件sense_stream,监听后端传来的sense_data
socket.on('sense_stream', function (sensor_data) {
                if (sensor_data) {
                    $("#senserVal").text(sensor_data);
                }
            })
  • 在后端主动发送信息流至前端时,使用socketio.emit(),指定连接空间和事件
socketio.emit('sense_stream', msg, broadcast=False, namespace=webUser)

图解

图解SocketIO工作流

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值