使用ActionController进行流式处理:: Live无法在生产中使用

时间:2015-01-14 21:46:12

标签: ruby-on-rails sidekiq server-sent-events puma

我正在使用Ruby on Rails 4.1,使用ActionController :: Live从Sidekiq流程传输数据。在开发中,我的流媒体工作非常棒。在制作中(使用Nginx / Puma),它并不是很好。这是发生了什么。

在制作中,参考我的Firebug下面的图片," / events"正在多次被解雇。 为什么我的EventSource会被反复触发而不是等待我的数据?这在开发中不会发生。

Firebug EventSource

只要我的Sidekiq进程正在运行,它将以随机间隔重复触发。一旦我的sidekiq进程完成,它将挂起并且不再启动。然后最后一个最终会超时(见图中的红色文字)

这是我的咖啡因:

source = new EventSource('/events')
source.addEventListener 'my_event', (e) ->
    console.log 'Got a message!'
    # Add the content to the screen somewhere

参考Firebug图像,它几乎就像我在Sidekiq过程中超时一样。我是从工人那里发帖到redis的。

初始化程序

REDIS = Redis.new(url: 'redist://localhost:6379')

Sidekiq工人

REDIS.publish('my_event', 'some data')

然后我将EventSource连接到的控制器操作:

def events
  response.headers["Content-Type"] = "text/event-stream"
  redis = Redis.new(url: "redist://localhost:6379")
  # blocks the current thread
  redis.subscribe(['my_event', 'heartbeat']) do |on|
    on.message do |event, data|
      if event == 'heartbeat'
        response.stream.write("event: heartbeat\ndata: heartbeat\n\n")
      elsif event == 'my_event'
        response.stream.write("event: #{event}\n")
        response.stream.write("data: #{data.to_json}\n\n")
      end
    end
  end
rescue IOError
  logger.info 'Events stream closed'
ensure
  logger.info 'Stopping events streaming thread'
  redis.quit
  response.stream.close
end

同样,这在开发过程中100%出色。来自Sidekiq的数据完全流向浏览器。上面的心跳是因为this answer(我有同样的问题)

有没有人看到我做错了什么?我错过了ActionController::Live使用Nginx / Puma进行制作的某种形式的设置吗?

重要提示

在来自图像的每个请求的非常结束时(它似乎超时并尝试进行下一个),我成功获得了一行数据。所以某些东西似乎在起作用。但是单EventSource并没有保持开放并且足够长时间地监听数据,它只是不断重复。

1 个答案:

答案 0 :(得分:6)

我最近的一个项目遇到了类似的问题。我发现这是我的nginx配置。

将以下内容添加到位置部分:

proxy_set_header Connection '';
proxy_http_version 1.1;
chunked_transfer_encoding off;
proxy_buffering off;
proxy_cache off;

此信息来自以下Stack Overflow讨论:

EventSource / Server-Sent Events through Nginx

希望这有帮助。