Rails ActionController::Live - Sends everything at once instead of async

假装没事ソ 提交于 2021-01-28 11:56:37

问题


I have an issue with rails ActionController::Live

In the end I want to show the progress of FFMPEG to the user, but for now I want to get this minimal example running:

Rails media_controller.rb:

class MediaController < ApplicationController
  include ActionController::Live

  def stream
    puts "stream function loaded"

      response.headers['Content-Type'] = 'text/event-stream'
      i = 0
      begin
        response.stream.write "data: 1\n\n"
        sleep 0.5
        i += 1
        puts "response... data: " + i.to_s
      end while i < 10
    response.stream.close
  end
end

Javascript:

source = new EventSource("/test/0");
source.addEventListener("message", function(response) {
  // Do something with response.data
  console.log('I have received a response from the server: ' + response);
}, false);

When I navigate to the site, there are no JavaScript Errors showing. As soon as I navigate to the site, the "stream"-Action of the MediaController gets successfully called. I can verify this, by looking at the Server-Console. It gives me the following output. After every response line, there is a 500ms delay, like expected:

stream function loaded
response... data: 1
response... data: 2
response... data: 3
response... data: 4
response... data: 5
response... data: 6
response... data: 7
response... data: 8
response... data: 9
response... data: 10
Completed 200 OK in 5005ms (ActiveRecord: 0.8ms)

On the JavaScript Side, it gives me the following Output:

(10x) I have received a response from the server: [object MessageEvent]

But the problem is here, that it sends all these 10 Messages from the server after 5 seconds at the same time! The expected behavior however is, that it should send me 1 message every 0.5 seconds!

So what am I doing wrong here? Where is the error?


回答1:


I could resolve the issue, by using a different Webserver. Previously I used thin and I found this Post on SO:

you can't use AC::Live with Thin

An Explanation can be found here:

https://github.com/macournoyer/thin/issues/254#issuecomment-67494889

Thin doesn't work with streaming and ActionController::Live.

The only approach that works with Thin is to use the async API: https://github.com/macournoyer/thin_async. Thin is built exactly for this kind of stuff and making it scale.

Or simpler, use this: https://github.com/SamSaffron/message_bus.

So switching to another Server solved the issue:

gem 'puma'

Starting with

rails s Puma


来源:https://stackoverflow.com/questions/35057075/rails-actioncontrollerlive-sends-everything-at-once-instead-of-async

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!