Class: EventStreamParser::Parser

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

Overview

Implements a spec-compliant event stream parser, following:

html.spec.whatwg.org/multipage/server-sent-events.html Section: 9.2.6 Interpreting an event stream

Code comments are copied from the spec.

Instance Method Summary collapse

Constructor Details

#initializeParser

Returns a new instance of Parser.



15
16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/event_stream_parser.rb', line 15

def initialize
  ##
  # When a stream is parsed, a data buffer, an event type buffer, and a last
  # event ID buffer must be associated with it. They must be initialized to
  # the empty string.
  #
  @data_buffer = +''
  @event_type_buffer = +''
  @last_event_id_buffer = +''

  @reconnection_time = nil
  @buffer = +''
  @last_delimiter = nil
end

Instance Method Details

#feed(chunk, &proc) ⇒ Object



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/event_stream_parser.rb', line 30

def feed(chunk, &proc)
  @buffer << chunk

  ##
  # The stream must then be parsed by reading everything line by line, with a
  # U+000D CARRIAGE RETURN U+000A LINE FEED (CRLF) character pair, a single
  # U+000A LINE FEED (LF) character not preceded by a U+000D CARRIAGE RETURN
  # (CR) character, and a single U+000D CARRIAGE RETURN (CR) character not
  # followed by a U+000A LINE FEED (LF) character being the ways in which a
  # line can end.
  #
  @buffer.delete_prefix!("\n") if @last_delimiter == "\r"

  while (line = @buffer.slice!(/.*?(?<delim>\r\n|\r|\n)/))
    line.chomp!
    @last_delimiter = $~[:delim]
    process_line(line, &proc)
  end
  ##
  # Once the end of the file is reached, any pending data must be discarded.
  # (If the file ends in the middle of an event, before the final empty line,
  # the incomplete event is not dispatched.)
  #
end

#streamObject



55
56
57
# File 'lib/event_stream_parser.rb', line 55

def stream
  proc { |chunk| feed(chunk) { |*args| yield(*args) } }
end