class SseRailsEngine::Manager

This class provides the ability to track SSE connections and broadcast events to all connected clients from anywhere in your Rails app.

Example Usage:

class MyController < ActionController::Base
  def do_stuff
    SseRailsEngine.send_event('event name', 'any ruby object or string for data')
  end
end

Note: SSEs are not currently supported by IE.

Constants

HEARTBEAT_EVENT
RackHijackUnsupported

Attributes

connections[R]
heartbeat_thread[R]

Public Class Methods

new() click to toggle source
# File lib/sse_rails_engine/manager.rb, line 23
def initialize
  @mutex = Mutex.new
  @connections = ThreadSafe::Cache.new

  start_heartbeats
end

Public Instance Methods

call(env) click to toggle source
# File lib/sse_rails_engine/manager.rb, line 59
def call(env)
  register(env)
  [-1, {}, []]
ensure
  ActiveRecord::Base.clear_active_connections! if defined?(ActiveRecord)
end
open_connection(io, env) click to toggle source
# File lib/sse_rails_engine/manager.rb, line 54
def open_connection(io, env)
  @connections[io] = Connection.new(io, env)
  Rails.logger.debug "New SSE Client connected: #{io} - #{@connections[io].channels}"
end
register(env) click to toggle source
# File lib/sse_rails_engine/manager.rb, line 30
def register(env)
  if env['rack.hijack']
    env['rack.hijack'].call
    socket = env['rack.hijack_io']
    # Perform full hijack of socket (http://old.blog.phusion.nl/2013/01/23/the-new-rack-socket-hijacking-api/)
    open_connection(socket, env)
  else
    raise RackHijackUnsupported, 'This Rack server does not support hijacking, ensure you are using >= v1.5 of Rack'
  end
end
send_event(name, data = '') click to toggle source
# File lib/sse_rails_engine/manager.rb, line 41
def send_event(name, data = '')
  @mutex.synchronize do
    @connections.each_pair do |stream, connection|
      begin
        connection.write(name, data)
      rescue StandardError => ex
        Rails.logger.debug "SSE Client disconnected: #{stream} - #{ex.message}"
        close_connection(stream)
      end
    end
  end
end

Private Instance Methods

close_connection(stream) click to toggle source
# File lib/sse_rails_engine/manager.rb, line 68
def close_connection(stream)
  return if @connections[stream].nil?
  @connections[stream].stream.close
  @connections.delete(stream)
end
start_heartbeats() click to toggle source
# File lib/sse_rails_engine/manager.rb, line 74
def start_heartbeats
  Rails.logger.debug 'Starting SSE heartbeat thread!'
  @heartbeat_thread = Thread.new do
    loop do
      sleep SseRailsEngine.heartbeat_interval
      send_event(HEARTBEAT_EVENT)
    end
  end
end