使用 ActionController::Live 进行流式传输在生产环境中不起作用
Streaming with ActionController::Live not working in production
我在 Rails 4.1 上使用 Ruby,使用 ActionController::Live 从 Sidekiq 进程流式传输数据。在开发中,我的流式传输非常棒。在生产环境中(使用 Nginx/Puma),它并没有那么顺利。这是正在发生的事情。
在生产中,参考下图我的 Firebug,“/events”被多次触发。 为什么我的 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 一起工作的某种形式的设置?
重要提示
在每个来自图像的请求的最后(似乎超时并尝试执行下一个请求),我成功地获得了一行数据。所以 something 似乎在起作用。但是单个 EventSource
没有保持打开状态并监听足够长的数据,它只是不断重复。
我在最近的一个项目中遇到了类似的问题。我发现这是我的 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
希望对您有所帮助。
我在 Rails 4.1 上使用 Ruby,使用 ActionController::Live 从 Sidekiq 进程流式传输数据。在开发中,我的流式传输非常棒。在生产环境中(使用 Nginx/Puma),它并没有那么顺利。这是正在发生的事情。
在生产中,参考下图我的 Firebug,“/events”被多次触发。 为什么我的 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 一起工作的某种形式的设置?
重要提示
在每个来自图像的请求的最后(似乎超时并尝试执行下一个请求),我成功地获得了一行数据。所以 something 似乎在起作用。但是单个 EventSource
没有保持打开状态并监听足够长的数据,它只是不断重复。
我在最近的一个项目中遇到了类似的问题。我发现这是我的 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
希望对您有所帮助。