【快速开始】一个简单的Flask-SocketIO应用,完成后端推送消息接收与关闭

效果图

先看运行效果图
【快速开始】一个简单的Flask-SocketIO应用,完成后端推送消息接收与关闭_第1张图片
【快速开始】一个简单的Flask-SocketIO应用,完成后端推送消息接收与关闭_第2张图片
【快速开始】一个简单的Flask-SocketIO应用,完成后端推送消息接收与关闭_第3张图片
OK,下面开始。

安装环境

本人使用环境及版本:
Anaconda:

虚拟环境:
Python版本:3.8.13
安装包及版本:
Flask-SocketIO:5.3.4
eventlet:0.33.3

快速开始

后端代码

创建app.py文件(文件名随意,不过要与后面的运行脚本中指定的文件保持一致)

import time
from flask import Flask, render_template, jsonify
from flask_socketio import SocketIO

service_state = 0
app = Flask(__name__)
socketio = SocketIO(app, cors_allowed_origins="*")

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

@app.route("/start_service")
def start_service():
    global service_state
    service_state = 0
    while service_state == 0:
        time_text = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(int(time.time())))
        print(">>>>>>", time_text)
        json_data = {"no": 1, "time": time_text, "msg": "......"}
        socketio.emit("service_msg", json_data)
        socketio.sleep(2)
    return jsonify({"start": True})


@app.route("/stop_service")
def stop_service():
    global service_state
    service_state = 9
    return jsonify({"stop": True})


if __name__ == "__main__":
    socketio.run(app, host="0.0.0.0", port=5200, debug=True, log_output=True)

前端代码

DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8"/>
        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
        <title>HCI Applicationtitle>
        <link rel="apple-touch-icon" sizes="76x76" href="{{url_for('static', filename='img/favicon.ico')}}">
        <link rel="icon" type="image/png" href="{{url_for('static', filename='img/favicon.ico')}}">
        <meta content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0, shrink-to-fit=no' name='viewport'/>
        
        <link rel="stylesheet" href="{{url_for('static', filename='fontawesome/css/all.css')}}">
        
        <link rel="stylesheet" href="{{url_for('static', filename='css/main.css')}}"/>
        
        <link rel="stylesheet" href="{{url_for('static', filename='css/vendor/aos.css')}}"/>
    head>
    <body> 
        
        <nav class="navbar navbar-expand-lg navbar-dark bg-purple fixed-top">
            <div class="container-fluid">
                <a class="navbar-brand" href="#"><i class="fas fa-robot mr-2">i><strong>HCIstrong> Applicationa>
                <div class="navbar-collapse collapse" id="navbarColor02">
                    <ul class="navbar-nav ml-auto d-flex align-items-center">
                        <li class="nav-item">
                            <input type="hidden" id="running_state" value="0">
                            <button type="button" 
                                    class="btn btn-block btn-primary btn-round mb-1"
                                    id="btn_running_state"
                                    onclick="run_serivce()">
                                <i class="fas fa-play" id="i_running_state_icon">i>
                                <b id="b_running_state_text">启动服务b>
                            button>
                        li>
                    ul>
                div>
            div>
        nav>
        
        <main class="container-fluid">
            <div class="position-relative">
                <div class="container-fluid text-dark mt-5 pt-5">
                    
                    <table class="table table-left table-hover" id="tbl_log">
                        <thead class="bg-primary text-white">
                            <tr align="left">
                                <th scope="col" style="width:120px;">#th>
                                <th scope="col" style="width:300px;">Timeth>
                                <th scope="col">消息内容th>
                            tr>
                        thead>
                        <tbody>
                            <tr align="center" class="text-black">
                                <th scope="row" colspan="3">等待启动 ...th>
                            tr>
                        tbody>
                    table>
                div>
            div>
        main>
            
        <script src="{{url_for('static', filename='js/vendor/jquery.min.js')}}" type="text/javascript">script>
        <script src="{{url_for('static', filename='js/vendor/popper.min.js')}}" type="text/javascript">script>
        <script src="{{url_for('static', filename='js/vendor/bootstrap.min.js')}}" type="text/javascript">script>
        <script src="{{url_for('static', filename='js/vendor/share.js')}}" type="text/javascript">script>
        <script src="{{url_for('static', filename='js/functions.js')}}" type="text/javascript">script>
        <script src="{{url_for('static', filename='js/vendor/aos.js')}}" type="text/javascript">script>
        <script src="{{url_for('static', filename='js/socket.io.js')}}" type="text/javascript">script>
        <noscript>
            <style>
                *[data-aos] {
                    display: block !important;
                    opacity: 1 !important;
                    visibility: visible !important;
                }
            style>
        noscript>
        <script>
            AOS.init({
                duration: 700,
                disable: function () {
                    var maxWidth = 1200;
                    return window.innerWidth < maxWidth;
                }
            });

            /*
            开启服务,获取分类运行结果
            */
            var line_number = 1;
            var socket = io();

            // 专门接收后端推送消息
            socket.on('service_msg', function(data) {
                var row = "" +
                                "" +  line_number + "" +
                                "" + data.time + "" +
                                "" + data.msg  + "" +
                            "";                                
                line_number++;
                //添加数据到 table 第一行
                $("#tbl_log tbody").prepend(row);
            });
            
            /*
            运行服务,开始接收推送消息
            */
            function run_serivce() {
                $("#btn_running_state").attr("onclick", "pause_service()");
                $("#i_running_state_icon").attr("class", "fas fa-pause");
                $("#b_running_state_text").html("暂停服务");
                var row = "启动成功,开始接收数据 ..."
                $("#tbl_log tbody").prepend(row);
                $.ajax({
                    type: "get",          // 请求方式
                    url: "start_service", // 请求路径
                    async: true,          // 异步请求
                    dataType: "json",     // 预期返回一个 json 类型数据
                    success: function (data) {   // data是形参名,代表返回的数据
                        console.log(data);
                    }
                });
            }

            /*
            暂停服务
            */
            function pause_service() {
                $("#btn_running_state").attr("onclick", "run_serivce()");
                $("#i_running_state_icon").attr("class", "fas fa-play");
                $("#b_running_state_text").html("启动服务");
                var row = "服务暂停,等待开启 ..."
                $("#tbl_log tbody").prepend(row);
                $.ajax({
                    type: "get",          // 请求方式
                    url: "stop_service",  // 请求路径
                    async: true,          // 异步请求
                    dataType: "json",     // 预期返回一个 json 类型数据
                    success: function (data) {   // data是形参名,代表返回的数据
                        console.log(data);
                    }
                });
            }
        script>
    body>
html>

运行步骤

cmd 或者 linux控制台运行即可

python app.py

此时能看到如下图所示
【快速开始】一个简单的Flask-SocketIO应用,完成后端推送消息接收与关闭_第4张图片
此时访问http://0.0.0.0:5200(0.0.0.0 替换成对应IP或者127.0.0.1或localhost即可看到图1-3效果)


代码理解

在python代码中,首先通过SocketIO封装flask app

socketio = SocketIO(app, cors_allowed_origins="*")

通过cors_allowed_origins="*"来指定支持跨域访问限制问题

另外设定全局变量service_state = 0用来控制服务运行状态,从而根据结果是否要向前端发送数据。

最后就是在启动接口/start_service上增加状态判断死循环,只要service_state = 0,就会不断向前端发送数据(我这加了2秒间歇),具体方法调用前面定义的socketio变量的emit函数即可,如下所示:

socketio.emit("service_msg", json_data)

而要停止推送服务的话,那只需要调用/stop_service改变全局变量service_state的值即可。

代码下载

【GitCode地址:flask_socketio_quickstart】

你可能感兴趣的:(技术笔记,flask,python,后端,推送,消息推送,SocketIO,Flask-SocketIO)