• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
MKT-porter
博客园    首页    新随笔    联系   管理    订阅  订阅
树莓派(4-3)网页服务器 flask为背景的 websocket网页返回数据

1例程

https://www.cnblogs.com/luozx207/p/9719597.html

2flask教程

https://flaskbook.com/#

安装

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 图标画图

画图需要移植传数据,我发现使用线程一堆问题,所以间接使用轮询,也就是接受完消息马上给服务器发送消息,服务器接收消息处理函数被触发然后马上会一个数据

程序结构

 

 网页图

 

 

  1.  修改服务器端口
  2. 修改命名空间
  3. 修改话题名字
  4. 修改触发延迟时间

 

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

  

打开网页访问

 

 

 

 

 

#异步模式开启线程用
posted on 2020-02-19 19:00  MKT-porter  阅读(676)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3