我开发了一个RoR 应用程序,它在后台使用resque-status.
我希望能够显示后台作业百分比状态的 CSS 进度条。
有没有办法从视图中(实时)获取作业状态,以便我可以更改进度条的值?
我自己一直在考虑这个!
您将需要使用一种称为推送技术的技术(与 iPhone 的“推送通知”相同)。这将使您能够向前端发送特定更新。
让我解释一下这个问题,以及如何解决它......
您遇到的问题是,发送持久更新不在 Rails 或 HTTP 的职权范围内。这些都建立在无状态协议模式之上,这意味着每个请求都在一个干净的状态。
这意味着除非您打开一个持久连接(您可以从中指定不同的数据属性),否则您将只能通过异步请求发送一次性更新
持久性
为了“跟踪进度”,您需要创建一个系统,首先推送您的数据(因此您需要一种接收该数据的方法),然后您需要能够处理您将收到的任何推送更新。这就是您能够创建进度条“外观”的方式。
有两种方法可以实现这一点:
这两者都有一个非常简单的工作方式(你可以在这里看到:什么是长轮询、Websockets、服务器发送事件(SSE)和彗星?)
它们本质上使您能够将前端DOM(通过 JS)连接到后端“推送”系统。然后,这将允许您的 JS 处理从后端发送到“侦听”JS 调用的任何更新。
我不会详细介绍 SSE / Websockets,除了说 websockets 是最好的解决方案——它们是真正持久的。SSE 只是对您的控制器端点使用 ajax 长轮询,效率极低且安全性较低。
--
推动
为了实现“进度条”类型的界面,您需要考虑以下模式:
- 您的用户的 DOM 使用 SSE / Websockets 连接到您的端点
- 使用发布/订阅模式,您将为每个用户提供一个频道
- 将推送通知发送到相应的频道
我建议为此使用一个名为Pusher的系统(无从属关系)。它是一个 websocket 接口,将您的前端连接到系统的后端控制器方法
这将允许您执行以下操作:
#app/assets/stylesheets/application.css.sass
.progress
background: #ccc
.bar
background: #f0f
#app/workers/your_job_worker.rb
class YourJobWorker
include Resque::Plugins::Status
def perform
# send update to pusher here
end
end
#app/assets/javascripts/application.js
var pusher = new Pusher('***');
var channel = pusher.subscribe('*****');
channel.bind('progress', function(data) {
$(".bar .progress").css("width", data + "%");
});
显然对你来说是一个非常粗略的大纲——希望能解释你如何解决这个问题的方法。