m2r
m2r copied to clipboard
Support for streaming / SSE
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.
Probably sender_id
and connection_uuid
should also be put into env hash.
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.
Related to #42
http://polycrystal.org/2012/04/15/asynchronous_responses_in_rack.html
- http://blog.phusion.nl/2013/01/23/the-new-rack-socket-hijacking-api/
- http://rack.rubyforge.org/doc/SPEC.html
- http://ngauthier.com/2013/03/websockets-in-rails-4.html