Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/398.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用Flask实现强制页面刷新的最佳方法是什么?_Javascript_Python_Html_Flask - Fatal编程技术网

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

Javascript 使用Flask实现强制页面刷新的最佳方法是什么?,javascript,python,html,flask,Javascript,Python,Html,Flask,背景 我有大量字段将从外部进程实时更新。我想定期更新Flask托管的页面,以向连接的用户显示任何更改。理想情况下,整个页面不会刷新,这是一个类似系统的投诉,而只是更新页面上的一些字段 当前方向 我目前的想法是使用JavaScript来处理这个问题,但我不确定在使用Flask时这是否可行 有没有办法通过Flask或第三方模块来实现这一点? 附加信息 数据将使用各种套接字和串行端口进行更新。每个接口都将在自己的线程中运行并更新共享内存。请注意,Flask/web接口具有对共享内存的只读写入,其他线程

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

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

有没有办法通过Flask或第三方模块来实现这一点?

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


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

我认为最简单的方法可能是使用javascript,正如您在问题中所建议的那样。在本例中,Flask将只提供一个HTML文档,其中包含一些要由浏览器执行的javascript代码,因此我不明白为什么这会给Flask带来任何问题。在中,我发现了一些使用不同组合的示例,例如使用计时器(这似乎是您正在寻找的)。

不。好吧,至少烧瓶的侧面没有什么比其他解决方案更容易做到这一点。所以有一些像样的材料

如前所述,您可以使用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)

为了避免刷新整个页面,您需要使用所谓的AJAX。看起来这很容易理解

因为您希望它定期发生,所以需要从javascript中的函数调用AJAX函数

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

实现这一点的一种方法是使用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>

WebSocket示例
$(文档).ready(函数(){
var socket=io.connect('http://'+document.domain+':'+location.port);
socket.on('connect',function(){
emit('am up',{data:'I'm connected!'});
});
//侦听套接字上的“价格更新”消息
socket.on('price update',函数(msg){
$('price#u info')。文本(msg)
});
});

您是如何从这个外部过程中获取数据的?谢谢您的示例。如果我被迫刷新整个页面,我相信它们会变得非常有用。您对如何刷新页面的一部分有什么想法吗?要只重新加载页面的一部分,您需要使用ajax查询web服务器以获取该部分页面的更新版本(并且您还需要在服务器端实现)。烧瓶文档中的这一部分应该有助于从这一点开始。感谢您的输入。这是我所害怕的(关于“否”)。查看我的编辑,了解预期用户数的详细信息。它们帮助很大。感谢您的输入,这似乎是我可以很快测试出来的东西。顺便说一句,我不喜欢你上次编辑的标题。我不知道刷新页面的最佳方法,所以我不想搜索AJAX或Comet。我觉得在我这种情况下,其他人也不会知道这一点。这给了我一个错误:feed.js:5 uncaughtreferenceerror:$SCRIPT\u ROOT未定义
<!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>