仅当烧瓶中的变量发生变化时才更新网站

Posted

技术标签:

【中文标题】仅当烧瓶中的变量发生变化时才更新网站【英文标题】:Updating a website only when variables change in flask 【发布时间】:2019-01-18 01:55:22 【问题描述】:

你好,*** 社区

我正在烧瓶中执行一个函数,该函数通过发布请求更新变量,然后处理该变量并将其显示到网站中,就像那些体育比分网站所做的那样。

网站按预期工作,但我计划有一些用户,我认为一旦变量 var_g 发生变化,它会比网站更新要好得多,而不是像现在那样每 2 秒执行一次,这将是令人难以置信的所有用户同时获得更新,希望你们能帮助我

任何建议都会很有帮助,我没有太多经验,也许我做错了。

烧瓶侧

from flask import Flask, jsonify, render_template, request

# Global variable to keep everything updated
var_g = 0

app = Flask(__name__)

# Getting the post resquest
@app.route('/read', methods=['GET', 'POST'])
def read():
    if request.method == 'POST':
        # Getting the data to update from headers of post request
        info = int(request.headers.get('info'))

        # Trying to keep the changes with a global variable
        global var_g
        var_g = info

    print(var_g)

    # Procesing data
    if var_g == 0:
        color = "No color"
    elif ( var_g > 0 and var_g < 100 ):
        color = "red"
    elif ( var_g >= 100 ):
        color = "blue"
    else:
        color = "Unknow"
    print(color)

    return jsonify(color = color)

# Index
@app.route('/', methods=['GET'])
def index():
    if request.method == 'GET':
        return render_template('index.html')

HTML端

<html>
  <head>
    <title> State of colors </title>
  </head>
<body>
    <p> The color state is  </p>
     <!--Conecting the results from function /read -->
    <p> <span id=results>  ---  </span> </p>

    <!--   json jquery  -  AJAX -->
    <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>

    <script type=text/javascript>
        function colors() 
            $.getJSON('/read',
            // Getting the updated color
            function(data) 
                // conecting results to jsonify
                $("#results").text(data.color);
            );
            // Updating every 2 secons
            setTimeout(function() 
                        colors();
            , 2000);
        
        // Starting on load
        window.onload = colors;
    </script>
  </body>
</html>

【问题讨论】:

对您所描述的内容使用 websockets 我正在使用Flask socket.io 执行此类任务。它使用起来超级简单,甚至比 AJAX 还要简单。 非常感谢 charlietfl 和 @Roman,我将更深入地了解 socket.io 【参考方案1】:

正如@charlietfl 所说,您需要使用WebSocket 发送服务器到客户端关于状态更新的通知。不幸的是,flask 然后不是最好的选择,因为它通常每个请求都需要一个线程经典方法。每个 websocket 连接都是一个长时间运行的请求,因此在使用烧瓶建立一定数量的连接后,您可能会用完线程(工作者)。一种可能的克服方法是从作为框架的烧瓶切换到asyncio。有一个很好的 aiohttp 库已经支持开箱即用的 HTTP 和 websockets 服务器。

这里是一个简单的例子,代码可能是什么样子(虽然没有运行它,可能需要一些调整):

import asyncio
import aiohttp.web

your_state_here = 'counter': 0

active_clients = []

async def index(request):
    return aiohttp.web.Response(text='<your template here>')


async def do_update(request):
    # your logic here

    your_state_here['counter'] += 1

    for ws in active_clients:
        ws.send_str('updated %s' % your_state_here['counter'])

    return aiohttp.web.Response(text='Ok')


async def on_state_update(request):
    ws = aiohttp.web.WebSocketResponse()
    await ws.prepare(request)

    active_clients.append(ws)

    async for msg in ws:
        if msg.type == aiohttp.WSMsgType.TEXT:
            if msg.data == 'close':
                active_clients.remove(ws)
                await ws.close()

    return ws


def main():
    loop = asyncio.get_event_loop()
    app = aiohttp.web.Application(loop=loop)
    app.router.add_route('GET', '/', index)
    app.router.add_route('POST', '/do_update', do_update)
    app.router.add_route('GET', '/updates', on_state_update)
    aiohttp.web.run_app(app, port=3000)


if __name__ == '__main__':
    main()

【讨论】:

非常感谢您抽出宝贵的时间@IvanVelichko,我肯定会四处看看 asyncio 和 WebSocket 的欢呼声。

以上是关于仅当烧瓶中的变量发生变化时才更新网站的主要内容,如果未能解决你的问题,请参考以下文章

仅当 Rails 中的属性发生更改时才运行回调

仅当连接明确时才更新行

仅当宽度和高度都更改时才更改图像大小

razor page (blazor) 正在对字符进行编码

仅当与 table2 中的 column3 匹配时才更新 table1 中的 column1

仅当记录匹配时才从另一个表中更新记录