When Rails introduced remote:true option for links (AJAX requests) I 
changed my view on how to handle javascript on my websites. I'm playing 
with streaming in Rails 4.1 (ActionController::Live) and I realized that a 
similar solution is needed for handling server events (EventSource).

Case: 
My website displays a list of tweets (http://localhost:3000/tweets). Every 
X seconds a new post is added to the list.

Solution:
Let's forget about live updates for a moment and imagine I would add a form 
above the list where I could write a tweet and post it to the server (POST 
/tweets) with <form ... remote:true>. In this case the create.js action 
view will execute a javascript code (that I would define) for adding a new 
tweet to the list (as described here: 
http://edgeguides.rubyonrails.org/contributing_to_ruby_on_rails.html#reporting-an-issue).
 
The logic for live updates should be very similar. The "only difference" in 
this case is that the create.js action is executed multiple times without 
refreshing the page. 
I built the server events logic similar to railscasts episode 401. When a 
new tweet is created send the create.js code to $redis channel, the content 
is sent to a client over /server_events controller-action and the code is 
evaluate with jquery.

# SERVER

GET /server_events
def server_events
   response.headers["Content-Type"] = "text/event-stream"
   redis = Redis.new
   redis.psubscribe("tweets.create") do |on|
      on.pmessage do |pattern, event, data|
         response.stream.write("id: #{Time.now.to_i}\n")
         response.stream.write("event: #{event}\n")
         response.stream.write("data: #{data}\n\n")
      end
    end
  rescue IOError
    logger.info "Stream closed"
  ensure
    redis.quit
    response.stream.close
end

POST /tweets
def create
   ...
   $redis.publish("tweets.create", render_to_string("tweets/create.js", 
layout: false, item: @tweet).to_json)
   ...
end

# CLIENT

sse = new EventSource('/server_events')
sse.addEventListener 'tweets.create', (e) ->
   $.globalEval($.parseJSON(e.data))

What do you think? Suggestions?

-- 
You received this message because you are subscribed to the Google Groups "Ruby 
on Rails: Core" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to rubyonrails-core+unsubscr...@googlegroups.com.
To post to this group, send email to rubyonrails-core@googlegroups.com.
Visit this group at http://groups.google.com/group/rubyonrails-core.
For more options, visit https://groups.google.com/d/optout.

Reply via email to