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>