Class: Simultaneous::Rack::EventSource

Inherits:
Object
  • Object
show all
Defined in:
lib/simultaneous/rack.rb

Overview

A Rack handler that allows you to create a HTML5 Server-Sent Events endpoint. Relies on EventMachine to easily handle multiple open connections simultaneously

To use, first create an instance of the EventSource class:

messenger = Simultaneous::Rack::EventSource.new

Then map this onto a URL in your application, e.g. in a RackUp file

app = ::Rack::Builder.new do
  map "/messages" do
    run messenger.app
  end
end
run app

In your web-page, set up an EventSource using the new APIs

source = new EventSource('/messages');
source.addEventListener('message', function(e) {
  alert(e.data);
}, false);

Then when you want to send a messages to all your clients you use your (Ruby) EventSource instance like so:

messenger.deliver("Hello!")

IMPORTANT:

This will only work when run behind Thin or some other, EventMachine driven webserver. See <github.com/matsadler/rack-async> for more info.

Instance Method Summary collapse

Constructor Details

#initializeEventSource

Returns a new instance of EventSource.



45
46
47
48
49
# File 'lib/simultaneous/rack.rb', line 45

def initialize
  @lock = Mutex.new
  @timer = nil
  @clients = []
end

Instance Method Details

#appObject



51
52
53
# File 'lib/simultaneous/rack.rb', line 51

def app
  #::Rack::Async.new(self)
end

#call(env) ⇒ Object



55
56
57
58
59
60
61
62
63
64
# File 'lib/simultaneous/rack.rb', line 55

def call(env)
  stream = env['async.body']
  stream.errback { cleanup!(stream) }

  @lock.synchronize { @clients << stream }

  # Nginx specific header to disable buffering
  # see: http://wiki.nginx.org/X-accel#X-Accel-Buffering
  [200, {"Content-type" => "text/event-stream", "X-Accel-Buffering" => "no"}, stream]
end

#deliver(data) ⇒ Object



70
71
72
# File 'lib/simultaneous/rack.rb', line 70

def deliver(data)
  send("data: #{data}\n\n")
end

#deliver_event(event) ⇒ Object



66
67
68
# File 'lib/simultaneous/rack.rb', line 66

def deliver_event(event)
  send(event.to_sse)
end