perplexes / m2r

Mongrel2 Connection Adapter - Ruby Encrusted Steel-Reinforced Fist
MIT License
90 stars 11 forks source link

Support for streaming / SSE #15

Open paneq opened 12 years ago

paneq commented 12 years ago

Idea: Allow to easily deliver notifications to clients from Rails/Rack apps using SSE.

Algorithm:

Subscription

From Rails/Rack application respond with Transfer-Encoding: chunked header for the request. Verify user and store sender_id and connection_uuid of his request somewhere (current thread, db, redis, whatever). This leaves open connection in the browser that can be used later for delivering SSE.

Sending notification

When there is an event that you would like to inform user about (ex. friend added a picture) send chunked part to the same sender_id, connection_uuid that we stored in db. Mongrel2 allows it and will forward to the browser.

If chunked response uses SSE format then it can be used by JS SSE API in HTML5 browsers.

Main areas of concern regarding integration with Rails

access from Rails app to handler

How can one use #deliver method from our handler in the Rails/Rack application. In other words, how can such higher level reach something from low-level ?

We could expose the handler itself in rack env.

env = {
  "rack.version" => Rack::VERSION,
  "rack.url_scheme" => "http",
  "rack.input" => StringIO.new(req.body),
  "rack.errors" => $stderr,
  "rack.multithread" => true,
  "rack.multiprocess" => true,
  "rack.run_once" => false,

  "mongrel2.pattern" => req.headers["PATTERN"],
  "mongrel2.handler" => self  # !!!

  "REQUEST_METHOD" => req.headers["METHOD"],
  "SCRIPT_NAME" => script_name,
  "PATH_INFO" => req.headers["PATH"].gsub(script_name, ''),
  "QUERY_STRING" => req.headers["QUERY"]
}

That would allow to reach it from Rails action in controller using:

request.env["mongrel2.handler"].deliver(...)

subscribing to disconnected event

I don't have yet an idea as how to subscribe from Rails app to on_disconnected event in the handler. I would like to avoid foricing users to inhreit from the RackHandler to plug in their application behavior.

paneq commented 12 years ago

Probably sender_id and connection_uuid should also be put into env hash.

paneq commented 11 years ago

Try to keep the API compatible with what Aaron describes here: http://www.youtube.com/watch?v=kufXhNkm5WU . Maybe just change the included module to M2R::Live ? Maybe that should be a different gem, but m2r responsibility is to keep it possible to be implemented.

paneq commented 11 years ago

Related to #42

paneq commented 11 years ago

http://polycrystal.org/2012/04/15/asynchronous_responses_in_rack.html

paneq commented 11 years ago