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

效果图

先看运行效果图
图1. 等待运行
图2.启动推送服务后效果
图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 Application</title>
        <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'/>
        <!-- Font Awesome Icons -->
        <link rel="stylesheet" href="{{url_for('static', filename='fontawesome/css/all.css')}}">
        <!-- Main CSS -->
        <link rel="stylesheet" href="{{url_for('static', filename='css/main.css')}}"/>
        <!-- Animation CSS -->
        <link rel="stylesheet" href="{{url_for('static', filename='css/vendor/aos.css')}}"/>
    </head>
    <body> 
        <!---------- NAVBAR ---------->
        <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>HCI</strong> Application</a>
                <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>
        <!-- End Navbar -->
        <main class="container-fluid">
            <div class="position-relative">
                <div class="container-fluid text-dark mt-5 pt-5">
                    <!-- table -->
                    <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;">Time</th>
                                <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>
        <!------------ JAVASCRIPTS ---------------->    
        <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 = "<tr>" +
                                "<th scope=\"row\">" +  line_number + "</th>" +
                                "<td align=\"left\">" + data.time + "</td>" +
                                "<td align=\"left\">" + data.msg  + "</td>" +
                            "</tr>";                                
                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 = "<tr align=\"center\" class=\"text-success\"><th scope=\"row\" colspan=\"3\">启动成功,开始接收数据 ...</th></tr>"
                $("#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 = "<tr align=\"center\" class=\"text-secondary\"><th scope=\"row\" colspan=\"3\">服务暂停,等待开启 ...</th></tr>"
                $("#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

此时能看到如下图所示
app运行效果
此时访问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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

黑符石

感谢小主对原创的大力支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值