使用Flask实现强制页面刷新的最佳方法是什么?

问题描述 投票:21回答:4

背景 我有大量的字段将从外部进程实时更新。我想定期更新Flask托管页面,以向连接的用户显示任何更改。理想情况下,整个页面不会刷新,这是对类似系统的抱怨,而只是更新页面上的许多字段。

当前方向 我目前的想法是使用可能使用JavaScript来处理这个问题,但我不确定在使用Flask时是否可行。

有没有办法使用Flask或第三方模块来实现这一目标?

附加信息 将使用各种套接字和串行端口更新数据。每个接口都将在其自己的线程中运行并更新共享内存。请注意,Flask / Web界面对共享内存具有只读写入,可由其他线程更新。

总客户端池不应超过20人。这是测试系统的Web界面,通常在任何给定时间只有1-5人连接到它。

javascript python html flask
4个回答
17
投票

要避免刷新整个页面,您需要使用所谓的AJAX。看起来这很容易implement in flask

由于您希望它定期发生,您需要在javascript中从timer函数调用您的AJAX函数。

这意味着您只需将烧瓶页面中的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

3
投票

我认为最简单的方法是使用你在问题中建议的javascript。在这种情况下,Flask只是提供一个HTML文档,其中包含一些浏览器要执行的javascript代码,所以我不明白为什么这会给Flask带来任何问题。在this page中,我发现了一些使用不同组合的例子,例如使用计时器(这似乎是你正在寻找的)。


2
投票

不,好吧,至少在Flask方面没有任何东西比其他解决方案更容易。 SO在implementing comet servers in Python上有一些不错的材料。

如您所述,您可以使用JavaScript轮询服务器以获取新数据。如果您有很多用户,那么您的服务器很难管理。打开并发TCP连接相当昂贵。这也意味着您的UI可能看起来有些不稳定,因为事情会每隔一秒左右更新一次,而不是在新数据到达服务器时。

考虑到这一点,Flask非常适合第二种选择,因为将响应函数附加到各个URL非常容易。需要注意的主要事项是你应该在I / O上严重阻塞的功能。长时间运行的功能将占用整个应用程序。

假设您有两个温度计,并且您正在使用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);

0
投票

实现这一目标的一种方法是使用flask-socketio在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>
© www.soinside.com 2019 - 2024. All rights reserved.