Обновление сайта только при изменении переменных во флаконе

Привет, сообщество stackoverflow

Я выполняю функцию во флаконе, которая обновляет переменную с помощью почтового запроса, а затем обрабатывает эту переменную и показывает ее на веб-сайте, как это делают веб-сайты спортивных прямых трансляций.

Веб-сайт работает так, как задумано, но я планирую иметь несколько пользователей, я думаю, это было бы намного лучше, чем обновление веб-сайта после изменения переменной 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>

Используйте веб-сокеты для того, что вы описываете

charlietfl 10.08.2018 14:41

Для таких задач я использую Фляга socket.io. Его очень просто использовать, даже проще, чем AJAX.

Roman 10.08.2018 15:48

На самом деле спасибо charlietfl и @Roman, я собираюсь подробнее узнать о socket.io

Jcgo3003 10.08.2018 17:24
2
3
218
1

Ответы 1

Как сказал @charlietfl, вам нужно использовать WebSocket для отправки уведомлений сервер к клиенту об обновлении состояния. К сожалению, flask в этом случае не лучший вариант, поскольку для него обычно требуется один поток на запрос при классическом подходе. Каждое соединение с веб-сокетом - это своего рода длительный запрос, поэтому после некоторого количества установленных подключений с использованием flask у вас могут закончиться потоки (рабочие). Один из возможных способов преодоления - переключиться с фляжки в качестве фреймворка на asyncio. Уже есть хорошая библиотека aiohttp для поддержки серверов HTTP и веб-сокетов из коробки.

Вот краткий пример того, как тогда мог бы выглядеть код (хотя не запускал его, может потребоваться некоторая корректировка):

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.

Jcgo3003 10.08.2018 17:28

Другие вопросы по теме