Skip to content

Instantly share code, notes, and snippets.

@karmi
Forked from rkh/Gemfile
Last active August 4, 2021 13:53
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save karmi/4954396 to your computer and use it in GitHub Desktop.
Save karmi/4954396 to your computer and use it in GitHub Desktop.
Sinatra + EventSource JavaScript Streaming

jQuery + Sinatra + Streaming

A server-side service outputs a long response using Sinatra's streaming API. How can the javascript client process this long response as a stream and refresh a pre in the HTML page until the whole response has been received?

To run it:

bundle install
bundle exec ruby app.rb

Then, try to implement the requested feature. See index.html

require 'sinatra'
set :server, :thin
get '/' do
send_file "index.html"
end
get '/bottles' do
# puts params.inspect
# puts request.body.read.inspect
# puts "Last-Event-Id: #{request.env['HTTP_LAST_EVENT_ID']}"
start = request.env['HTTP_LAST_EVENT_ID'] ? request.env['HTTP_LAST_EVENT_ID'].to_i+1 : 0
content_type "text/event-stream"
stream do |out|
start.upto(50) do |i|
out << "id: #{i}\n"
out << "data: #{i} bottle(s) on a wall...\n\n"
sleep 0.3
end
out << "data: CLOSE\n\n"
end
end
source "http://rubygems.org/"
gem "sinatra", "~> 1.3.0"
gem "thin"
<!DOCTYPE html>
<html lang="fr">
<head>
<title>Sinatra streaming example</title>
<meta charset="utf-8" />
<!--[if lt IE 9]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<script src="http://code.jquery.com/jquery-1.9.0.min.js"></script>
<style>body {font-family: sans-serif;}</style>
</head>
<body>
<h1>Welcome to this Sinatra Streaming example!</h1>
<input id="bottles-button" type="button" value="Bottles!"/>
<pre id="bottles-output">
</pre>
<script>
$("#bottles-button").click(function() {
var src = new EventSource('/bottles?foo=bar');
src.onmessage = function(e) {
console.log(e)
$('#bottles-output').append("\n" + e.data)
if ( e.data == 'CLOSE' ) src.close()
};
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment