Class: Firehose::Rack::Consumer::HttpLongPoll
- Inherits:
-
Object
- Object
- Firehose::Rack::Consumer::HttpLongPoll
- Includes:
- Helpers
- Defined in:
- lib/firehose/rack/consumer.rb
Constant Summary collapse
- TIMEOUT =
How long should we wait before closing out the consuming clients web connection for long polling? Most browsers timeout after a connection has been idle for 30s.
20
Instance Method Summary collapse
Methods included from Helpers
Instance Method Details
#call(env) ⇒ Object
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/firehose/rack/consumer.rb', line 34 def call(env) req = env['parsed_request'] ||= ::Rack::Request.new(env) path = req.path method = req.request_method # Get the Last Message Sequence from the query string. # Ideally we'd use an HTTP header, but android devices don't let us # set any HTTP headers for CORS requests. last_sequence = req.params['last_message_sequence'].to_i case method # GET is how clients subscribe to the queue. When a messages comes in, we flush out a response, # close down the requeust, and the client then reconnects. when 'GET' Firehose.logger.debug "HTTP GET with last_sequence #{last_sequence} for path #{path} with query #{env["QUERY_STRING"].inspect} and params #{req.params.inspect}" EM.next_tick do if last_sequence < 0 env['async.callback'].call response(400, "The last_message_sequence parameter may not be less than zero", response_headers(env)) else Server::Channel.new(path).(last_sequence, :timeout => TIMEOUT).callback do |, sequence| env['async.callback'].call response(200, wrap_frame(, sequence), response_headers(env)) end.errback do |e| if e == :timeout env['async.callback'].call response(204, '', response_headers(env)) else Firehose.logger.error "Unexpected error when trying to GET last_sequence #{last_sequence} for path #{path}: #{e.inspect}" env['async.callback'].call response(500, 'Unexpected error', response_headers(env)) end end end end # Tell the web server that this will be an async response. ASYNC_RESPONSE else Firehose.logger.debug "HTTP #{method} not supported" response(501, "#{method} not supported.") end end |