class EzPaaS::HTTP::SSE::EventSource

An EventSource instance is used to parse a stream in the format given by the Server Sent Events standard: www.whatwg.org/specs/web-apps/current-work/#server-sent-events

Attributes

json[RW]

@!attribute json [rw]

@return [Boolean] (true) Whether to parse event's data field as JSON.
json?[RW]

@!attribute json [rw]

@return [Boolean] (true) Whether to parse event's data field as JSON.
last_event_id[R]

@!attribute last_event_id [r]

@return [String] the id of the last fully received event, or nil if no
events have been received containing an id field.
retry[R]

@!attribute retry [r]

@return [Fixnum] the last retry field received, or nil if no retry fields
have been received.

Public Class Methods

new() click to toggle source
# File lib/ezpaas/http/sse/event_source.rb, line 27
def initialize
  @json   = true
  @on     = {}
  @all    = []
  @buffer = ""
end

Public Instance Methods

feed(chunk) click to toggle source

Feed a chunk of data to the EventSource and dispatch any fully receieved events. @param [String] chunk the data to parse

# File lib/ezpaas/http/sse/event_source.rb, line 37
def feed chunk
  @buffer << chunk

  while i = @buffer.index("\n\n")
    process_event @buffer.slice!(0..i)
  end
end
message(&block) click to toggle source

Listens to all messages

# File lib/ezpaas/http/sse/event_source.rb, line 51
def message &block
  @all << block
end
on(name, &block) click to toggle source

Adds a listener for :name:

# File lib/ezpaas/http/sse/event_source.rb, line 46
def on name, &block
  (@on[name.to_sym] ||= []) << block
end

Protected Instance Methods

dispatch_event(data, id, name) click to toggle source
# File lib/ezpaas/http/sse/event_source.rb, line 84
def dispatch_event data, id, name
  data  = JSON.parse(data) if json?
  name  = (name || :message).to_sym
  event = Event.new(data, name, id)
  ((@on[name] || []) + @all).each { |p| p.call event }
end
process_event(s) click to toggle source
# File lib/ezpaas/http/sse/event_source.rb, line 56
def process_event s
  data, id, name = [], nil, nil
  s.lines.map(&:chomp).each do |line|
    field, value = case line
    when /^:/ then
      next # comment, do nothing
    when /^(.*?):(.*)$/ then
      [$1, $2]
    else
      [line, ''] # this is what the spec says, I swear!
    end
    # spec allows one optional space after the colon
    value = value[1..-1] if value.start_with? ' '
    case field
    when 'data' then
      data << value
    when 'id' then
      id = value
    when 'event' then
      name = value.to_sym
    when 'retry' then
      @retry = value.to_i
    end
  end
  @last_event_id = id
  dispatch_event data.join("\n"), id, name
end