Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@maccman
Created June 26, 2012 02:49
Show Gist options
  • Star 83 You must be signed in to star a gist
  • Fork 13 You must be signed in to fork a gist
  • Save maccman/2992949 to your computer and use it in GitHub Desktop.
Save maccman/2992949 to your computer and use it in GitHub Desktop.
Sinatra Server Side Event streaming.
# Usage: redis-cli publish message hello
require 'sinatra'
require 'redis'
conns = []
get '/' do
erb :index
end
get '/subscribe' do
content_type 'text/event-stream'
stream(:keep_open) do |out|
conns << out
out.callback { conns.delete(out) }
end
end
Thread.new do
redis = Redis.connect
redis.psubscribe('message', 'message.*') do |on|
on.pmessage do |match, channel, message|
channel = channel.sub('message.', '')
conns.each do |out|
out << "event: #{channel}\n\n"
out << "data: #{message}\n\n"
end
end
end
end
__END__
@@ index
<article id="log"></article>
<script>
var source = new EventSource('/subscribe');
source.addEventListener('message', function (event) {
log.innerText += '\n' + event.data;
}, false);
</script>
@rklubenspies
Copy link

@daviddesberg
Copy link

You should use document.getElementById('log'). Accessing an element by its id in a globally-scoped variable is a relic of ancient versions of Internet Explorer which, for whatever reason; Google decided to implement in V8. It is non-standard and bad practice, though; and won't work in Firefox.

@niklas
Copy link

niklas commented Oct 5, 2014

Thank you for that inspiration, I almost used faye..

There is a typo (?) in line 27, there should be only one newline to keep both lines close together:

      conns.each do |out|
        out << "event: #{channel}\n"
        out << "data: #{message}\n\n"
      end

Else the pushed message won't have the right type bound, and source.addEventListener('different'..) won't react at all.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment