LoginSignup
14
15

More than 5 years have passed since last update.

Rails4.0.0.beta1 + ActionController::Live + JavaScript EventSource

Last updated at Posted at 2013-02-27

app/controllers/progress_controller.rb

require 'reloader/sse'

class ProgressController < ApplicationController
  include ActionController::Live

  def index
    # SSE expects the `text/event-stream` content type
    response.headers['Content-Type'] = 'text/event-stream'

    sse = Reloader::SSE.new(response.stream)

    begin
      total = 0

      (0..100).step(10).each{ |i|
        puts "[ #{i} ]"
        sse.write( "#{Time.now.strftime("%Y/%m/%d %H:%M:%S")}" + " - #{i}" )
        total += i
        sleep( rand(1..3) )
      }

      puts "[ total : #{total} ]"

      sse.write( "#{Time.now.strftime("%Y/%m/%d %H:%M:%S")}" + " - #{total}", event: 'refresh' )

      # 接続終了送信
#      sse.write("stream_end")
    rescue IOError
      # When the client disconnects, we'll get an IOError on write
    ensure
      sse.close
    end
  end

  def show
  end
end

lib/reloader/sse.rb

require 'json'

module Reloader
  class SSE
    def initialize io
      @io = io
    end

    def write object, options = {}
      options.each do |k,v|
        @io.write "#{k}: #{v}\n"
      end
#      @io.write "data: #{JSON.dump(object)}\n\n"
      @io.write "data: #{object}\n\n"
    end

    def close
      @io.close
    end
  end
end

app/views/progress/show.html.erb

<h1>progress#show</h1>

<h3>Total</h3>

<div id="refresh"></div>

<hr />

<h3>Progress</h3>

<div id="progress"></div>

<script type="text/javascript">
  jQuery(document).ready(function() {
    setTimeout(function() {
      // 接続開始
      var source = new EventSource('/progress/index');

      // サーバー側イベントの共通ハンドラを定義
      function eventLogger(event){
        $("#progress").prepend(event.data + "<br>");

        // 接続終了判定
        if (event.data == 'stream_end') { source.close() };
      }

      // messageイベントのハンドラを設定
      source.onmessage = eventLogger;
    }, 10);
  });
</script>

<script type="text/javascript">
  jQuery(document).ready(function() {
    setTimeout(function() {
      var source = new EventSource('/progress/index');
      source.addEventListener('refresh', function(e) {
        $("#refresh").prepend(event.data + "<br>");
        // window.location.reload();

        // 接続終了判定
        if (event.data == 'stream_end') { source.close() };
      });
    }, 20);
  });
</script>

config/routes.rb

  get 'progress/index'
  get 'progress/show'

Gemfile

gem "puma"
bundle install
rails s puma

on Heroku

config/environments/production.rb

  # Disable Rails's static asset server (Apache or nginx will already do this).
#  config.serve_static_assets = false

Procfile

web: bundle exec rails s puma -p $PORT -e $RACK_ENV
git init && git add . && git commit -m "First commit"
heroku create rails4sample
git push heroku master


14
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
15