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+unsubscribe@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.