基于 Flask 和 Socket.IO 的 WebSocket 实时数据更新实现

news2024/11/29 19:37:55

简介

随着现代化应用的快速发展,实时数据交互已经成为许多 Web 应用的核心需求,比如实时消息推送、数据监控大屏等。本文将基于一个完整的 WebSocket 实现示例,带你一步步理解如何使用 Flask 和 Socket.IO 构建实时数据更新的 Web 应用。
将实现一个实时数据监控大屏,数据会通过后台自动生成,并以 WebSocket 的方式实时推送到前端页面进行展示

背景

为什么选择 WebSocket?
传统的 HTTP 协议是无状态的,服务端和客户端之间的交互通常是基于请求-响应模式。如果需要实时更新数据,比如展示销售额、访问量等统计信息,那么通常需要客户端定时向服务端发起轮询请求。但这种方式有明显的缺点:

效率低下:轮询会消耗大量的资源,因为大多数情况下数据并未改变,但轮询仍然会占用带宽和计算资源。
延迟较高:无法达到毫秒级的实时性,特别是在高频场景中,数据更新的延迟可能导致用户体验下降。
相比之下,WebSocket 是一种持久化的双向通信协议,可以在客户端和服务端之间建立全双工连接,能够更高效地实现实时数据的双向传输。这使得 WebSocket 成为实时应用的首选技术。

项目实现的核心功能

服务端:

  • 使用 Flask 框架和 Flask-SocketIO 实现 WebSocket 协议。
  • 后台自动生成模拟数据(如销售额、访问量、订单数等)。
  • 将生成的数据通过 WebSocket 实时推送到客户端。

客户端:

  • 通过 Socket.IO 客户端接收服务端推送的数据。
  • 动态更新页面内容并展示实时变化。
  • 提供美观的前端界面,模拟数据监控大屏的效果。

环境准备

在开始之前,请确保你的开发环境中安装了以下工具:

  • Python 3.x
  • Flask
  • Flask-SocketIO

你可以通过以下命令安装相关依赖库:

pip install flask flask-socketio

服务端实现

from flask import Flask, render_template
from flask_socketio import SocketIO, emit
import random
import time
from threading import Thread

# 创建 Flask 应用
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app)

# 模拟数据生成函数
def generate_random_data():
    """后台线程:生成模拟数据并推送到客户端"""
    while True:
        # 生成随机数据
        data = {
            'sales': random.randint(1000, 5000),  # 销售额
            'visitors': random.randint(100, 1000),  # 访问量
            'orders': random.randint(50, 200),  # 订单数
            'timestamp': time.strftime('%H:%M:%S')  # 当前时间
        }
        # 推送数据到客户端
        socketio.emit('update_data', data)
        time.sleep(2)  # 每 2 秒生成一次数据

# 首页路由
@app.route('/')
def index():
    return render_template('index.html')

# WebSocket 事件:客户端连接
@socketio.on('connect')
def handle_connect():
    print('Client connected')
    emit('server_response', {'data': 'Connected to server!'})

# WebSocket 事件:客户端断开连接
@socketio.on('disconnect')
def handle_disconnect():
    print('Client disconnected')

# WebSocket 事件:接收客户端消息
@socketio.on('client_message')
def handle_message(message):
    print('Received message:', message)
    # 将客户端消息广播给所有连接的客户端
    emit('server_response', {'data': message['data']}, broadcast=True)

# 主函数:启动应用
if __name__ == '__main__':
    # 启动后台线程
    Thread(target=generate_random_data, daemon=True).start()
    # 启动 Flask-SocketIO 服务
    socketio.run(app, debug=True, host='0.0.0.0', port=5000)

服务端代码解析

  1. Flask-SocketIO 的使用
    Flask-SocketIO 是基于 Flask 的扩展库,支持 WebSocket 协议,可以轻松实现实时通信。

    socketio = SocketIO(app)
    
  2. 后台数据生成线程
    使用 Python 的 Thread 模块在后台不断生成随机数据并通过 socketio.emit 方法推送到客户端。

    Thread(target=generate_random_data, daemon=True).start()
    
  3. WebSocket 事件监听

    • @socketio.on('connect'):当客户端连接时触发。
    • @socketio.on('disconnect'):当客户端断开连接时触发。
    • @socketio.on('client_message'):监听客户端发送的消息,并将其广播给所有连接的客户端。

前端实现

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>实时数据大屏</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.0.1/socket.io.js"></script>
    <style>
        body {
            margin: 0;
            padding: 20px;
            background-color: #1a1a1a;
            color: #fff;
            font-family: Arial, sans-serif;
        }
        .dashboard {
            display: grid;
            grid-template-columns: repeat(3, 1fr);
            gap: 20px;
            max-width: 1200px;
            margin: 0 auto;
        }
        .card {
            background-color: #2a2a2a;
            border-radius: 10px;
            padding: 20px;
            text-align: center;
            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
        }
        .card h2 {
            margin: 0 0 10px 0;
            color: #4CAF50;
        }
        .value {
            font-size: 2.5em;
            font-weight: bold;
            margin: 10px 0;
        }
        .timestamp {
            text-align: right;
            color: #888;
            margin-top: 20px;
        }
        @keyframes pulse {
            0% { transform: scale(1); }
            50% { transform: scale(1.05); }
            100% { transform: scale(1); }
        }
        .update {
            animation: pulse 0.5s ease-in-out;
        }
    </style>
</head>
<body>
    <h1 style="text-align: center; margin-bottom: 40px;">实时数据监控</h1>
    <div class="dashboard">
        <div class="card">
            <h2>销售额</h2>
            <div id="sales" class="value">0</div>
            <div>实时销售金额 (元)</div>
        </div>
        <div class="card">
            <h2>访问量</h2>
            <div id="visitors" class="value">0</div>
            <div>当前访问人数</div>
        </div>
        <div class="card">
            <h2>订单数</h2>
            <div id="orders" class="value">0</div>
            <div>实时订单统计</div>
        </div>
    </div>
    <div class="timestamp" id="timestamp">最后更新时间: --:--:--</div>

    <script>
        const socket = io();

        // 更新数据的函数
        function updateValue(elementId, value) {
            const element = document.getElementById(elementId);
            element.textContent = value;
            element.classList.remove('update');
            void element.offsetWidth; // 触发重绘
            element.classList.add('update');
        }

        // 监听数据更新事件
        socket.on('update_data', function(data) {
            updateValue('sales', data.sales);
            updateValue('visitors', data.visitors);
            updateValue('orders', data.orders);
            document.getElementById('timestamp').textContent = '最后更新时间: ' + data.timestamp;
        });
    </script>
</body>
</html>

前端代码解析

  1. 引入 Socket.IO 客户端库
    引入 Socket.IO 客户端库,用于与服务端建立 WebSocket 连接。

    <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.0.1/socket.io.js"></script>
    
  2. 动态更新数据的实现
    前端 JavaScript 代码通过监听 update_data 事件来获取服务端推送的数据,然后更新对应的 HTML 元素内容,并通过 CSS 动画增加视觉效果。

    socket.on('update_data', function(data) {
        updateValue('sales', data.sales);
        updateValue('visitors', data.visitors);
        updateValue('orders', data.orders);
        document.getElementById('timestamp').textContent = '最后更新时间: ' + data.timestamp;
    });
    
  3. 样式和布局
    使用 CSS Grid 布局创建整洁的数据卡片界面,每个卡片显示一种数据类型。卡片使用动画效果突出数据更新。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2249949.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

十、Spring Boot集成Spring Security之HTTP请求授权

文章目录 往期回顾&#xff1a;Spring Boot集成Spring Security专栏及各章节快捷入口前言一、HTTP请求授权工作原理二、HTTP请求授权配置1、添加用户权限2、配置ExceptionTranslationFilter自定义异常处理器3、HTTP请求授权配置 三、测试接口1、测试类2、测试 四、总结 往期回顾…

详细介绍HTTP与RPC:为什么有了HTTP,还需要RPC?

目录 一、HTTP 二、RPC 介绍 工作原理 核心功能 如何服务寻址 如何进行序列化和反序列化 如何网络传输 基于 TCP 协议的 RPC 调用 基于 HTTP 协议的 RPC 调用 实现方式 优点和缺点 使用场景 常见框架 示例 三、问题 问题一&#xff1a;是先有HTTP还是先有RPC&…

【Linux】 进程是什么

0. 什么是进程&#xff0c;为什么要有进程&#xff1f; 1.操作系统为了更好的管理我们的软硬件&#xff0c;抽象出了许多概念&#xff0c;其中比较有代表的就是进程了。通俗的来说操作系统为了更好的管理加载到内存的程序&#xff0c;故引入进程的概念。 2.在操作系统学科中用P…

[OpenHarmony5.0][Docker][环境]OpenHarmony5.0 Docker编译环境镜像下载以及使用方式

T. 已测试目录 主机类型主机版本Docker镜像版本结果WSL2Ubuntu22.04Ubuntu20.04PASSWSL2Ubuntu22.04Ubuntu18.04PASS R. 软硬件要求&#xff1a; 编译硬件需求&#xff1a;做多系统测试&#xff0c;磁盘500GB起步(固态)&#xff08;机械会卡死&#xff09;&#xff0c;内存3…

vue3-使用vite创建项目

vue-cli处于维护模式&#xff0c;也可以使用脚手架正常创建vue3项目&#xff0c;与vue2创建方式一致 官方推荐使用vite创建项目 vite 是新一代前端构建工具,官网地址轻量快速的热重载&#xff08;HMR&#xff09;&#xff0c;能实现极速的服务启动。对 TypeScript、JSX、CSS 等…

Java设计模式笔记(一)

Java设计模式笔记&#xff08;一&#xff09; &#xff08;23种设计模式由于篇幅较大分为两篇展示&#xff09; 一、设计模式介绍 1、设计模式的目的 让程序具有更好的&#xff1a; 代码重用性可读性可扩展性可靠性高内聚&#xff0c;低耦合 2、设计模式的七大原则 单一职…

Vue3+node.js实现登录

文章目录 前端代码实现后端代码实现跨域处理 前端代码实现 效果图 前端代码实现 <template><div class"login-container"><el-card class"login-card"><template #header><div class"card-header"><span>…

网络原理(一)—— http

什么是 http http 是一个应用层协议&#xff0c;全称为“超文本传输协议”。 http 自 1991 年诞生&#xff0c;目前已经发展为最主流使用的一种应用层协议。 HTTP 往往基于传输层的 TCP 协议实现的&#xff0c;例如 http1.0&#xff0c;http1.0&#xff0c;http2.0 http3 是…

Next.js-样式处理

#题引&#xff1a;我认为跟着官方文档学习不会走歪路 Next.js 支持多种为应用程序添加样式的方法&#xff0c;包括&#xff1a; CSS Modules&#xff1a;创建局部作用域的 CSS 类&#xff0c;避免命名冲突并提高可维护性。全局 CSS&#xff1a;使用简单&#xff0c;对于有传统…

navicat premium连接sqlserver

连接不上就双击安装图中的msi文件之后再连试试&#xff01;

Axure RP教程:创建高效用户界面和交互

Axure RP是一款广受好评的软件&#xff0c;专门用于设计精致的用户界面和交互体验。这款软件提供了众多UI控件&#xff0c;并根据它们的用途进行了分类。与此同时&#xff0c;国产的即时设计软件作为Axure的替代品&#xff0c;支持在线协作和直接在浏览器中使用&#xff0c;无需…

Qt导出Excel图表

目的 就是利用Qt导出Excel图表,如果直接画Excel 图表&#xff0c;比较麻烦些&#xff0c;代码写得也复杂了&#xff1b;而直接利用Excel模块就简单了&#xff0c;图表在模块当中已经是现成的了&#xff0c;Qt程序只更改数据就可以了&#xff0c;这篇文章就是记录一下利用模块上…

DeSTSeg: Segmentation Guided Denoising Student-Teacher for Anomaly Detection

DeSTSeg: Segmentation Guided Denoising Student-Teacher for Anomaly Detection 清华、苹果 个人感觉 Introduction 很自然的让读者理解作者问题的提出&#xff0c;也有例子直接证明了这个问题的存在&#xff0c;值得借鉴&#xff01;&#xff01; Related work写的也很不…

Java设计模式 —— 【创建型模式】工厂模式(简单工厂、工厂方法模式、抽象工厂)详解

文章目录 前言一、简单工厂&#xff08;静态工厂&#xff09;1、概述2、代码实现3、优缺点 二、工厂方法模式1、概述2、代码实现3、优缺点 三、抽象工厂模式1、概述2、代码实现3、优缺点 四、总结 前言 先看个案例&#xff1a;【手机和手机店】在没有工厂的时候&#xff0c;手…

利用Java爬虫获取阿里巴巴中国站跨境属性的详细指南

在全球化贸易的浪潮中&#xff0c;跨境电商正成为连接全球买家和卖家的重要桥梁。阿里巴巴中国站作为全球领先的B2B电子商务平台&#xff0c;提供了海量的商品信息&#xff0c;其中跨境属性信息对于跨境电商尤为重要。本文将详细介绍如何使用Java编写爬虫&#xff0c;从阿里巴巴…

「Qt Widget中文示例指南」如何为窗口实现流程布局?(二)

Qt 是目前最先进、最完整的跨平台C开发工具。它不仅完全实现了一次编写&#xff0c;所有平台无差别运行&#xff0c;更提供了几乎所有开发过程中需要用到的工具。如今&#xff0c;Qt已被运用于超过70个行业、数千家企业&#xff0c;支持数百万设备及应用。 本文将展示如何为不…

鸿蒙学习使用模拟器运行应用(开发篇)

文章目录 1、系统类型和运行环境要求2、创建模拟器3、启动和关闭模拟器4、安装应用程序包和上传文件QA:在Windows电脑上启动模拟器&#xff0c;提示未开启Hyper-V 1、系统类型和运行环境要求 Windows 10 企业版、专业版或教育版及以上&#xff0c;且操作系统版本不低于10.0.18…

Java后端如何进行文件上传和下载 —— 本地版

简介&#xff1a; 本文详细介绍了在Java后端进行文件上传和下载的实现方法&#xff0c;包括文件上传保存到本地的完整流程、文件下载的代码实现&#xff0c;以及如何处理文件预览、下载大小限制和运行失败的问题&#xff0c;并提供了完整的代码示例。 大体思路 1、文件上传 …

SqlServer强制转换函数TRY_CONVERT和TRY_CAST

SqlServer强制转换函数TRY_CONVERT和TRY_CAST的介绍和案例分享 1、本节内容 CAST 和 CONVERT TRY_CAST TRY_CONVERT 适用于&#xff1a; SQL ServerAzure SQL 数据库Azure SQL 托管实例Azure Synapse Analytics 分析平台系统 (PDW)Microsoft Fabric 中的 SQL 分析端点Micro…

透视投影(Perspective projection)与等距圆柱投影(Equirectangular projection)

一、透视投影 1.方法概述 Perspective projection&#xff08;透视投影&#xff09;是一种模拟人眼观察三维空间物体时的视觉效果的投影方法。它通过模拟观察者从一个特定视点观察三维场景的方式来创建二维图像。在透视投影中&#xff0c;远处的物体看起来比近处的物体小&…