Skip to content

Instantly share code, notes, and snippets.

@delba
Last active December 17, 2015 04:59
Show Gist options
  • Select an option

  • Save delba/5554367 to your computer and use it in GitHub Desktop.

Select an option

Save delba/5554367 to your computer and use it in GitHub Desktop.
Using Server-send Events with Rails
document.getElementById('new_message').reset()
Hermes::Application.configure do
config.cache_classes = true
config.eager_load = true
end
gem 'puma'
gem 'redis'
<ul id="messages">
<%= content_tag_for :li, @messages do |message| %>
<%= message.content %>
<%= link_to "Destroy", message, method: :delete, remote: true %>
<% end %>
</ul>
<%= form_for Message.new, remote: true do |f| %>
<%= f.text_field :content, autofocus: true, autocomplete: 'off' %>
<% end %>
source = new EventSource('/messages/events')
source.addEventListener 'messages:create', (e) ->
message = JSON.parse(e.data)
li = document.createElement('li')
li.id = "message_#{message.id}"
li.className = 'message'
li.innerText = message.content
document.getElementById('messages').appendChild(li)
source.addEventListener 'messages:destroy', (e) ->
message = JSON.parse(e.data)
document.getElementById("message_#{message.id}").remove()
class MessagesController < ApplicationController
include ActionController::Live
def index
response.headers['Content-Type'] = 'text/html'
@messages = Message.all
end
def create
response.headers['Content-Type'] = 'text/javascript'
message = Message.create!(message_params)
redis_publish message
end
def destroy
response.headers['Content-Type'] = 'text/javascript'
message = Message.find(params[:id]).tap(&:destroy!)
redis_publish message
head :ok
end
def events
response.header['Content-Type'] = 'text/event-stream'
redis = Redis.new
redis.psubscribe('messages:*') do |on|
on.pmessage do |pattern, event, data|
response.stream.write "event: #{event}\n"
response.stream.write "data: #{data}\n\n"
end
end
rescue IOError
logger.info "Stream Closed"
ensure
response.stream.close
end
private
def message_params
params.require(:message).permit(:content)
end
def redis_publish(message)
$redis.publish "messages:#{action_name}", message.to_json
end
end
$redis = Redis.new(host: 'localhost', port: 6379)
Hermes::Application.routes.draw do
resources :messages do
collection { get :events }
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment