Create a gist now

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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>
@thelucid

This comment has been minimized.

Show comment
Hide comment
@thelucid

thelucid Jun 26, 2012

Don't you need to set your log variable, i.e. "var log = document.getElementById('log');".

Don't you need to set your log variable, i.e. "var log = document.getElementById('log');".

@maccman

This comment has been minimized.

Show comment
Hide comment
@maccman

maccman Jun 26, 2012

Nope, elements can be referenced from JavaScript by their ID.

Owner

maccman commented Jun 26, 2012

Nope, elements can be referenced from JavaScript by their ID.

@jrom

This comment has been minimized.

Show comment
Hide comment
@jrom

jrom Jun 27, 2012

OMG I can't believe I just discovered this tip.

mind blown

jrom commented Jun 27, 2012

OMG I can't believe I just discovered this tip.

mind blown

@thelucid

This comment has been minimized.

Show comment
Hide comment
@thelucid

thelucid Jun 27, 2012

That's what I said when replying on Twitter... 14 years of JavaScript and then I come across this. Made me feel at little daft :)

That's what I said when replying on Twitter... 14 years of JavaScript and then I come across this. Made me feel at little daft :)

@pahagon

This comment has been minimized.

Show comment
Hide comment
@pahagon

pahagon Aug 15, 2012

try do this without chrome/v8

pahagon commented Aug 15, 2012

try do this without chrome/v8

@rklubenspies

This comment has been minimized.

Show comment
Hide comment
@Lusitanian

This comment has been minimized.

Show comment
Hide comment
@Lusitanian

Lusitanian Aug 30, 2012

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.

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

This comment has been minimized.

Show comment
Hide comment
@niklas

niklas 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.

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