Class: H2::Server::Stream::EventSource

Inherits:
Object
  • Object
show all
Includes:
HeaderStringifier
Defined in:
lib/h2/server/stream/event_source.rb

Constant Summary collapse

DATA_TEMPL =
"data: %s\n\n"
EVENT_TEMPL =
"event: %s\n#{DATA_TEMPL}"
SSE_HEADER =
{
  STATUS_KEY    => '200',
  :content_type => 'text/event-stream'
}

Instance Method Summary collapse

Constructor Details

#initialize(stream:, headers: {}) ⇒ H2::Server::Stream::EventSource

build and return EventSource instance, ready for pushing out data or named events. checks accept header in the request, then responds with valid headers for beginning an SSE stream

Parameters:

  • stream: (H2::Server::Stream)

    the Stream instance

  • headers: (Hash) (defaults to: {})

    optional headers to add to the intial response



23
24
25
26
27
28
29
30
31
# File 'lib/h2/server/stream/event_source.rb', line 23

def initialize stream:, headers: {}
  @closed  = false
  @stream  = stream
  @parser  = @stream.stream
  @headers = headers

  check_accept_header
  init_response
end

Instance Method Details

#check_accept_headerObject

checks accept header in the request and raises a StreamError if not valid for SSE



36
37
38
39
40
41
# File 'lib/h2/server/stream/event_source.rb', line 36

def check_accept_header
  accept = @stream.request.headers['accept']
  unless accept == SSE_HEADER[:content_type]
    raise StreamError, "invalid header accept: #{accept}"
  end
end

#closeObject

emit a final frame on this stream with end_stream flag



77
78
79
80
# File 'lib/h2/server/stream/event_source.rb', line 77

def close
  @parser.data ''
  @closed = true
end

#closed?Boolean

Returns true if this stream is closed.

Returns:

  • (Boolean)

    true if this stream is closed



84
85
86
# File 'lib/h2/server/stream/event_source.rb', line 84

def closed?
  @closed
end

#data(str) ⇒ Object

send out a message with the given data

this would be handled by ‘es.onmessage((msg)=>{})`

Parameters:

  • data (String)

    associated with this event



70
71
72
73
# File 'lib/h2/server/stream/event_source.rb', line 70

def data str
  d = DATA_TEMPL % str
  @parser.data d, end_stream: false
end

#event(name:, data:) ⇒ Object

send out a named event with the given data

this would be handled by ‘es.addEventListener(’name’, (msg)=>{})‘

Parameters:

  • name: (String)

    the name of the event

  • data: (String)

    data associated with this event



59
60
61
62
# File 'lib/h2/server/stream/event_source.rb', line 59

def event name:, data:
  e = EVENT_TEMPL % [name, data]
  @parser.data e, end_stream: false
end

#init_responseObject

responds with SSE headers on this stream



45
46
47
48
49
50
# File 'lib/h2/server/stream/event_source.rb', line 45

def init_response
  headers = SSE_HEADER.merge @headers
  @parser.headers stringify_headers(headers)
rescue ::HTTP2::Error::StreamClosed => sc
  @stream.log :warn, "stream closed early by client"
end