Last active
March 7, 2024 15:05
-
-
Save arashm/9840345 to your computer and use it in GitHub Desktop.
A simple chat app to demonstrate a pub/sub system using Redis and Server-Sent Event(SSE). You can see if you open two browsers, both browsers will get updates when user submits a message.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
# A simple chat app to demonstrate a pub/sub system using | |
# Redis and Server-Sent Event(SSE) | |
require 'sinatra' | |
require 'sinatra/streaming' | |
require 'redis' | |
require 'json' | |
set :port, 3000 | |
html = <<-EOT | |
<html><head> | |
<style> | |
body { font-size: 16px; } | |
input#message { width: 300px; } | |
input#username { width: 100px; } | |
input { padding: 10px } | |
</style> | |
</head><body> | |
<form> | |
<!--- there should be a 'name' or serializeArray in JQ wont work ---> | |
<input name='username' id='username' placeholder='Username' value='Guest' /> | |
<input name='message' id='message' placeholder='Send your message' /> | |
<input type='submit' value='send' > | |
</form> | |
<div id="messages"> | |
</div> | |
<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script> | |
<script> | |
function show_message(name, value) { | |
$('#messages').append("<p><b>" + name + ": </b>" + value + "</p>" ) | |
$('#message').val('') | |
} | |
// Connect to SSE | |
var source = new EventSource('/subscribe'); | |
// When a message received | |
source.onmessage = function(event) { | |
var data = JSON.parse(event.data); | |
show_message(data['username'], data['message']); | |
} | |
source.onerror = function(event) { | |
console.log('got error :('); | |
} | |
// Post the message when form submitted | |
$('form').submit( function(event) { | |
var form = $(this); | |
$.post('/send', | |
form.serializeArray() | |
); | |
event.preventDefault(); | |
}); | |
</script> | |
</body></html> | |
EOT | |
get('/') { html } | |
post '/send' do | |
redis = Redis.new | |
# params => {"username"=>"ArashM", "message"=>"Hi"} | |
redis.publish 'simple:chat', {username: params['username'], message: params['message']}.to_json | |
end | |
get '/subscribe' do | |
content_type 'text/event-stream' | |
redis = Redis.new | |
# For more information on streamin in sintara, see: | |
# http://www.sinatrarb.com/contrib/streaming.html | |
stream do |out| | |
# Listening to 'simple:chat' channel | |
redis.subscribe('simple:chat') do |on| | |
on.message do |event, data| | |
data = JSON.parse(data) | |
# There should be "data:" at the begining or it wont work. see: | |
# https://developer.mozilla.org/en-US/docs/Server-sent_events/Using_server-sent_events | |
out.puts "data: {\"username\":\"#{data['username']}\",\"message\":\"#{data['message']}\"}\n" unless out.closed? | |
out.flush | |
out.errback do | |
logger.warn "lost connection" | |
end | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment