![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/f369287f91d69c8fe83308005ceabcfb.png)
代码框架
后端
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)