Skip to content

Instantly share code, notes, and snippets.

@vanstee
Created November 30, 2010 17:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vanstee/722019 to your computer and use it in GitHub Desktop.
Save vanstee/722019 to your computer and use it in GitHub Desktop.
redis chat app
require 'sinatra'
require 'redis'
require 'json'
require 'sanitize'
redis = Redis.new
get '/' do
@index = redis.llen 'messages'
erb :index
end
get '/messages/since/:index' do
index = params[:index].to_i
length = redis.llen 'messages'
return nil if index == length
messages = redis.lrange 'messages', params[:index], length
messages.collect! { |message| JSON.parse(message) }
{:index => length, :messages => messages}.to_json
end
post '/message' do
unless params[:message].empty?
message = { :name => Sanitize.clean(params[:name]), :message => Sanitize.clean(params[:message]) }.to_json
redis.rpush 'messages', message
end
nil
end
enable :inline_templates
__END__
@@index
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/3.2.0/build/cssreset/reset-min.css" />
<style type="text/css">
html, body { background-color: #eeeeee; font: 18px Helvetica; color: #222222; }
ul.container { margin: 0 auto; width: 600px; }
ul.container > li { margin: 10px; background-color: #ffffff; }
ul.container > li.input { border: 1px solid #cccccc; }
ul.container > li.input > input { width: 538px; height: 22px; margin: 13px 20px; padding: 0; border: 0; outline: none; }
ul.container > li.input > span { width: 200px; font-weight: bold; position: absolute; margin: 14px 0 0 -220px; text-align: right; }
ul.message > li { border: 1px solid #cccccc; margin: -1px 0 0 0; }
ul.message > li > p { margin: 15px 20px; }
ul.message > li > span { width: 200px; font-weight: bold; position: absolute; margin: 14px 0 0 -220px; text-align: right; }
</style>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
<script>
$(document).ready(function() {
$('input').keypress(function(event) {
if(event.keyCode == '13') {
event.preventDefault();
$name = $('input#name');
if($name.val() == '') {
$('span.name').remove();
$name.val($(this).val());
}
else {
$.post('/message', {name: $name.val(), message: $(this).val()});
}
$(this).val('');
return false;
}
});
poll();
});
function poll() {
xhr = $.ajax({
url: '/messages/since/' + $('input#index').val(),
type: 'GET',
dataType: 'json',
success: function(data) {
if(data) {
$('input#index').val(data.index);
for(var i = 0; i < data.messages.length; i++) {
add(data.messages[i].name, data.messages[i].message);
}
}
},
error: function() {}
});
setTimeout(poll, 1000);
}
function add(name, message) {
if(name == $('span.name:last').text()) {
message = '<li>' +
' <p>' + message + '</p>' +
'</li>';
$message = $(message);
$message.hide();
$('ul.message').children().last().after($message);
}
else {
message = '<li>' +
' <ul class="message">' +
' <li>' +
' <span class="name">' + name + '</span>' +
' <p>' + message + '</p>' +
' </li>' +
' </ul>' +
'</li>';
$message = $(message);
$message.hide();
$('ul.message').last().parent().after($message);
}
$message.animate({ opacity: 1, height: 'toggle' }, 'fast');
$('body').animate({ scrollTop: $('body').height() }, 'fast');
}
</script>
</head>
<body>
<input type="hidden" id="name" />
<input type="hidden" id="index" value="<%= @index %>" />
<ul class="container">
<li>
<ul class="message">
<li>
<p>Welcome to the chat.</p>
</li>
</ul>
</li>
<li class="input">
<span class="name">Nickname</span>
<input type="text" />
</li>
</ul>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment