Подтвердить что ты не робот

Каков наилучший способ реализовать принудительное обновление страницы с помощью Flask?

Фон
У меня есть большое количество полей, которые будут обновлять реальное время от внешнего процесса. Я хотел бы периодически обновлять размещенные страницы Flask, чтобы показать подключенным пользователям любые изменения. В идеале, вся страница не обновлялась, это было жалобой на подобную систему, а просто обновляло несколько полей на странице.

Текущее направление
Мои текущие мысли - использовать, возможно, использовать JavaScript, чтобы справиться с этим, но я не уверен, что это возможно даже при использовании Flask.

Есть ли способ с Flask или сторонним модулем для выполнения этого?

Дополнительная информация
Данные будут обновляться с использованием различных сокетов и последовательных портов. Каждый интерфейс будет работать в своем потоке и обновлять общую память. Обратите внимание, что Flask/web-интерфейс имеет запись только для чтения в общую память, которая может быть обновлена ​​другими потоками.

Общий пул клиентов не должен превышать 20 человек. Это веб-интерфейс к тестовой системе, и в общем случае к нему будет подключено только 1-5 человек в любой момент времени.

4b9b3361

Ответ 1

Чтобы не обновлять всю страницу, вы хотите использовать то, что называется AJAX. Похоже, что это легко реализовать в фляге.

Поскольку вы хотите, чтобы это происходило периодически, вам нужно вызвать функции AJAX из функции timer в javascript.

Это означает, что вы просто поместите javascript со страницы фляжки внутри вызова таймера.

Здесь примерно то, что будет выглядеть javascript:

setInterval(                               //Periodically 
  function()
  {
     $.getJSON(                            //Get some values from the server
        $SCRIPT_ROOT + '/get_values',      // At this URL
        {},                                // With no extra parameters
        function(data)                     // And when you get a response
        {
          $("#result").text(data.result);  // Write the results into the 
                                           // #result element
        });
  },
  500);                                    // And do it every 500ms

Ответ 2

Я думаю, что самый простой способ сделать это - использовать javascript, как вы уже указываете в своем вопросе. В этом случае Flask будет просто доставлять HTML-документ, содержащий код javascript, который будет выполняться браузером, поэтому я не понимаю, почему это может вызвать проблемы с Flask. В этой странице, я нашел несколько примеров, используя различные комбинации, такие как использование таймера (который, кажется, то, что вы ищете).

Ответ 3

Нет. Ну, как ничто в стороне от Flask, это сделало бы это проще, чем другие решения. SO имеет некоторый достойный материал на внедрении кометных серверов в Python.

Как вы упомянули, вы можете использовать JavaScript для опроса сервера для новых данных. Это может быть сложно для вашего сервера, хотя, если у вас много пользователей. Открытие параллельных TCP-соединений довольно дорого. Это также означает, что ваш пользовательский интерфейс может выглядеть слегка рывком, потому что все будет обновляться каждую секунду или около того, а не когда новые данные попадают на сервер.

Учитывая это, Flask отлично подходит для этого второго выбора, потому что так легко подключать функции ответа к отдельным URL-адресам. Главное отметить, что вам следует выполнять функции, которые сильно блокируют ввод-вывод. Долгосрочные функции захватят все приложение.

Скажем, у вас есть два температурных датчика, и вы используете jQuery.

@app.route('/gauge/<int:gauge_id>')
def gauge_temp(gauge_id):
    temp = temp_from_db(gauge_id) #implement this yourself
    return dict(temp=temp, gauge_id=gauge_id)

В файле JavaScript вы можете получить некоторую функцию, которая обновляет элемент DOM каждую минуту с текущей температурой. Этот код должен дать вам некоторое представление о том, что вы можете построить в реальной реализации:

function updateTemp(gauge_id, selector) {
  $.getJSON('/gauge/' + gauge_id, function(data){
    $(selector).text = response.temp;
  })
}

setInterval('updateTemp(1, "#gauge-1")', 1000 * 60);
setInterval('updateTemp(2, "#gauge-2")', 1000 * 60);

Ответ 4

Один из способов добиться этого - в Flask через WebSockets, используя флакон-сокет. Я использую APScheduler для фонового процесса в примере, но любой фоновый процесс будет делать. это обновляет цену на веб-странице каждые 4 секунды:

from flask import Flask, render_template
from apscheduler.schedulers.background import BackgroundScheduler
from flask_socketio import SocketIO, emit

app = Flask(__name__)
socketio = SocketIO(app)

#defines the job
def job():
    new_price = get_new_price();
    #job emits on websocket
    socketio.emit('price update',new_price, broadcast=True)

#schedule job
scheduler = BackgroundScheduler()
running_job = scheduler.add_job(job, 'interval', seconds=4, max_instances=1)
scheduler.start()

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

if __name__ == '__main__':
    socketio.run(app, host='0.0.0.0')

Затем шаблон index.html:

<!DOCTYPE HTML>
<html>
<head>
    <title>WebSockets Example</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
    <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/socket.io/1.3.6/socket.io.min.js"></script>
    <script type="text/javascript" charset="utf-8">
       $(document).ready(function(){

           var socket = io.connect('http://' + document.domain + ':' + location.port);

           socket.on('connect', function() {
               socket.emit('am up', {data: 'I\'m connected!'});
           });
           //listens to 'price update' message on socket
           socket.on('price update', function(msg) {
               $('#price_info').text(msg)
           });

       });
   </script>
</head>
<body>
  <div id="price_info"></div>
</body>
</html>