在Ruby on Rails中实现作业完成时的通知/警报弹出窗口

时间:2014-02-04 12:25:30

标签: javascript ruby-on-rails ruby callback sidekiq

我正在使用'Sidekiq'gem在Rails中实现后台处理作业,这些作业在用户点击按钮时运行。由于作业是异步运行的,因此rails会立即回复。

我想添加一个功能或回调来触发JavaScript弹出窗口,以显示作业处理已完成。

Controller Snippet:

def exec_job
   JobWorker.perform_async(@job_id,@user_id)
   respond_to do |wants|
      wants.html {  }
      wants.js { render 'summary.js.haml' }
   end
end

编辑1: 我正在存储'user_id'以跟踪触发作业的用户。这样我就可以将弹出窗口与此用户联系起来。

编辑2: Sidekiq的'perform'方法执行一些数据库操作(主要是更新)和日志创建,这需要时间。

目前,用户在稍后刷新页面时会了解状态。

编辑3(解决方案尝试1):

我尝试在成功登录用户后使用订阅实现'Faye推送通知'(通道为user_id)。

在服务器端,当作业完成执行时,我创建了另一个客户端以将消息发布到同一个通道(使用faye参考文档)。

它在我的桌面上工作正常,即我可以看到一个警告弹出窗口,提示作业已完成。但是,当我尝试使用本地网络上的其他计算机进行测试时,不会提示警报。

客户端脚本:

(function() {
    var faye = new Faye.Client('http://Server_IP:9292/faye');
    var public_subscription = faye.subscribe("/users/#{current_user.id}", function(data) {
        alert(data);
    });
});

服务器端代码:

EM.run {
  client = Faye::Client.new('http://localhost:9292/faye')
  publication = client.publish("/users/#{user.id}", 'Execution completed!')

  publication.callback do
    logger.info("Message sent to channel '/users/#{user.id}'")
  end

  publication.errback do |error|
    logger.info('There was a problem: ' + error.message)
  end
}

2 个答案:

答案 0 :(得分:0)

Rails 4引入了ActionController::Live模块。这允许将SSE推送到浏览器。如果要基于数据库更新实现此功能,则需要考虑将Postgresql配置为LISTEN and NOTIFY

class MyController < ActionController::Base
  include ActionController::Live

  def stream
    response.headers['Content-Type'] = 'text/event-stream'
    100.times {
      response.stream.write "hello world\n"
      sleep 1
    }
  ensure
    response.stream.close
  end
end

以下是一篇很好的文章:http://ngauthier.com/2013/02/rails-4-sse-notify-listen.html

答案 1 :(得分:0)

谢谢fmendez。

我查看了其他用户提出的建议,最后,我通过以下方式实施了基于'Faye'的推送通知:

  1. 订阅用户成功登录使用'user_id'
  2. 创建的频道
  3. 作业完成后从服务器端回复此频道(通过提取user_id)
  4. 为了更好地理解(以便对其他人有帮助),请检查问题的编辑。