1例程
https://www.cnblogs.com/luozx207/p/9719597.html
2flask教程
安装
pip install flask-socketio
例程
都放在树莓派才行

tem里面放着网页

样例1 -简单双向测试
https://juejin.im/post/5bdad42bf265da392a7e2e0e#heading-10

- json文件貌似自动解析了
python文件
from flask import Flask, render_template
from flask_socketio import SocketIO,emit
import datetime,random #导入时间和随机数模块
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app)
@app.route('/')
def index():
return render_template('index.html')
# 接受消息-初次链接
@socketio.on('connect', namespace='/')
def test_connect():
#发送消息-给命名空间“/”下的话题[client_msg]发送消息
# emit('client_msg', {'data': 'Connected'})
pass
# 接受消息-话题[sever_msg]消息message(json格式)到来自动触发
# 例子 消息message-{data: 'I\'m connected!'}
@socketio.on('sever_msg', namespace='/')
def test_message(message):
#发送消息-给命名空间“/”下的话题[client_msg]发送消息message(json数据)
#message是可以直接使用的json数据-直接访问
time_now = datetime.datetime.now().strftime('%H:%M:%S')
send_msg = {'time':time_now,'data':random.randint(1,10),'message':message['data']}
emit('client_msg',
send_msg,
broadcast=True)
#print('接收:'+message['data'])
if __name__ == '__main__':
socketio.run(app,'0.0.0.0',8080)
网页
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script type="text/javascript" src="//code.jquery.com/jquery-1.4.2.min.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/socket.io/1.3.5/socket.io.min.js"></script>
</head>
<body>
<h2>客户端</h2>
<script type="text/javascript">
//网页加载好开始运行
$(document).ready(function() {
/*建立链接*/
namespace = '/';//建立web链接的地址 /
var socket = io.connect(location.protocol + '//' + document.domain + ':' + location.port + namespace);
/*通信开始*/
//(RC1)网页接收话题[connect]消息。
socket.on('connect', function() {
//(SD1)网页发送给服务器话题[sever_msg]消息
socket.emit('sever_msg', {data: 'I\'m connected!'});
});
//(RC2)网页接收话题[client_msg]消息。 msg不需要转换json可以直接用
socket.on('client_msg', function(msg)
{
//消息框提示
//alert(msg);//已经是json格式,不是文本格式
alert(msg.data);
alert(msg.time);
alert(msg.message);
});
});
</script>
</body>
</html>
样例2- 建议网页聊天室

from flask import Flask, render_template
from flask_socketio import SocketIO,emit
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app)
@app.route('/')
def index():
return render_template('index.html')
@socketio.on('imessage', namespace='/')
def test_message(message):
emit('message', #//后端广播信息的事件名最好跟前端发送信息的事件名不一样
{'data': message['data']},
broadcast=True)
if __name__ == '__main__':
socketio.run(app,'0.0.0.0',8080)
关键就是要在emit中加broadcast=True这一项,如果不加,只有发送信息的客户端能收到消息
socketio.run()函数封装了flask的web服务器的启动
网页

打开两个网页都连接到http://127.0.0.1:5000/,测试一下,一个网页发送的信息在另一个网页也可以及时收到。一个简陋的多人聊天系统完成了:)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script type="text/javascript" src="//code.jquery.com/jquery-1.4.2.min.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/socket.io/1.3.5/socket.io.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
namespace = '/';
var socket = io.connect(location.protocol + '//' + document.domain + ':' + location.port + namespace);
//连接后发送日志
socket.on('connect', function(){
console.log('connected')
});
//点击发送时将text框的内容发送到后端
$('form#emit').submit(function(event) {
socket.emit('imessage', {data: $('#emit_data').val()});
return false;
});
//接收后端广播的信息
socket.on('message', function(msg) {
$('#log').append('<br>' + $('<div/>').text(msg.data).html());
});
});
</script>
</head>
<body>
<form id="emit" method="POST" action='#'>
<input type="text" name="emit_data" id="emit_data" placeholder="Message">
<input type="submit" value="发送">
</form>
<h2>Receive:</h2>
<div id="log"></div>
</body>
</html>
样例3 图标画图
画图需要移植传数据,我发现使用线程一堆问题,所以间接使用轮询,也就是接受完消息马上给服务器发送消息,服务器接收消息处理函数被触发然后马上会一个数据

程序结构

网页图

- 修改服务器端口
- 修改命名空间
- 修改话题名字
- 修改触发延迟时间
from flask import *
from flask_socketio import *
import datetime,random #导入时间和随机数模块
from multiprocessing import Process, Value, Array
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app,async_mode=None)
@app.route('/')
def index():
return render_template('flask_chart_v1 (1).html', async_mode=socketio.async_mode)
# 接受消息-初次链接
@socketio.on('connect', namespace='/test_chart')
def test_connect():
print('1')
pass
# 接受消息-话题[sever_msg]消息message(json格式)到来自动触发
# 例子 消息message-{data: 'I\'m connected!'}
@socketio.on('sever_msg', namespace='/test_chart')
def test_message(message):
#发送消息-给命名空间“/”下的话题[client_msg]发送消息message(json数据)
#message是可以直接使用的json数据-直接访问
socketio.sleep(1)#异步时间
time_now = datetime.datetime.now().strftime('%H:%M:%S')
send_msg = {'time':time_now,'data':random.randint(1,10)}
emit('client_msg',
send_msg,
namespace='/test_chart')
#print('接收:'+message['data'])
if __name__ == '__main__':
socketio.run(app,'0.0.0.0',8081)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>WebSocket demo</title>
</head>
<body>
<h1> 光照强度 </h1>
<canvas id="panel" height="330px" width="700px"> </canvas> <!--折线图位置-->
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script> <!--导入jQuery-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/1.0.2/Chart.min.js"></script> <!--导入jQuery-->
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/socket.io/1.3.5/socket.io.min.js"></script>
<script language="javascript" type="text/javascript" >
//网页加载好开始运行
$(document).ready(function() {
// 画图板-创建
var can = $('#panel').get(0).getContext('2d'); /*绘制类型*/
// 画图板-定义图标的数据
var canData = {
labels:["a","b","c","d","e","f"], /*初始x轴数据*/
datasets : [
{
//折线的填充颜色
fillColor:"rgba(255,255,255,0.1)",
//线条颜色:
strokeColor:"rgba(255,255,0,1)",
//y轴初始数据:
data:[1,3,2,1,5,4]
}
]
};
// 画图板-初始化绘制数据
var line = new Chart(can).Line(canData);
/*建立链接*/
namespace = '/test_chart';//建立web链接的地址 /
var socket = io.connect(location.protocol + '//' + document.domain + ':' + location.port + namespace);
/*通信开始*/
//(RC1)网页接收话题[connect]消息。
socket.on('connect', function() {
//(SD1)网页发送给服务器话题[sever_msg]消息
socket.emit('sever_msg', {data: 'I\'m connected!'});
});
//(RC2)网页接收话题[client_msg]消息。
socket.on('client_msg', function(msg)
{
//alert(msg.time);
var time = msg.time;
var data = msg.data;
// 画图板-画线
line.addData(
[data], //y轴,因为同一个x轴可以有多个折线
[time] //x轴
);
// 画图板-画线保证8个数据,多的剔除
var len = line.datasets[0].points.length;
if(len>8){
line.removeData()
}
//触发下个数据到来- 服务器接受话题sever_msg处理函数
socket.emit('sever_msg', {data:'Next data!'});
});//socket.on结束
});
</script>
</body>
</html>
4用例
- flask创建线程,websocket的返回本机数据
- 网页websocket接收打印
- websocket使用命名空间
- flask服务器使用本地文件

服务器
websocket.py
#encoding:utf-8
#!/usr/bin/env python
import psutil
import time
from threading import Lock
from flask import Flask, render_template
from flask_socketio import SocketIO
#异步模式开启线程用
async_mode = None
#修改默认网页服务器静态文件路径地址
app = Flask(
__name__,
template_folder='.', # 表示在当前目录 (myproject/A/) 寻找模板文件
static_folder='', # 空 表示为当前目录 (myproject/A/) 开通虚拟资源入口
static_url_path='',
)
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app, async_mode=async_mode)
#异步模式开启线程用
thread = None
thread_lock = Lock()
# 后台线程 产生数据,即刻推送至前端
def background_thread():
count = 0
while True:
socketio.sleep(1)
count += 1
t = time.strftime('%M:%S', time.localtime())
# 获取系统时间(只取分:秒)
cpus = psutil.cpu_percent(interval=None, percpu=True)
# 获取系统cpu使用率 non-blocking
socketio.emit('server_response',
{'data': [t, cpus], 'count': count},
namespace='/test')
# 注意:这里不需要客户端连接的上下文,默认 broadcast = True
@app.route('/')
def index():
return render_template('websocket.html', async_mode=socketio.async_mode)
#命名空间 /test 开启线程
@socketio.on('connect', namespace='/test')
def test_connect():
global thread
with thread_lock:
if thread is None:
thread = socketio.start_background_task(target=background_thread)
if __name__ == '__main__':
socketio.run(app,'0.0.0.0',8080,debug=True)
websocket.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>系统监控走势图</title>
<script type="text/javascript" src="//cdn.bootcss.com/jquery/3.1.1/jquery.min.js"></script>
<script type="text/javascript" src="//cdn.bootcss.com/socket.io/1.5.1/socket.io.min.js"></script>
</head>
<body>
<script type="text/javascript">
// 建立socket连接,等待服务器“推送”数据,用回调函数更新图表
$(document).ready(function() {
namespace = '/test';
var socket = io.connect(location.protocol + '//' + document.domain + ':' + location.port + namespace);
socket.on('connect', function(){
console.log('connected')
});
//接受话题 F12打印消息
socket.on('server_response', function(res) {
res.data[0]
console.log(res)
//console.log(res.data[0])
});
//发送消息
socket.emit('imessage',{'data': 1, 'count': 1});
});
</script>
</body>
</html>
运行服务器
python websocket.py
打开网页访问

#异步模式开启线程用
浙公网安备 33010602011771号