websockets, ruby y pusher webprendedor 2010
DESCRIPTION
TRANSCRIPT
WebSockets in Ruby(and things you can do with them)
Ismael Celis @ismasan github.com/ismasan
new bamboo
new-bamboo.co.uk pusherapp.com
Friday, 19 November 2010
Polling
Long-polling
Web socket
websockets.org/about.html
HTML5 Web sockets
Friday, 19 November 2010
Casos de uso
•Chat
•Aplicaciones financieras
• Juegos
•Presencia de usuarios
•Colaboración
•Notificaciones Tiempo Real
Friday, 19 November 2010
WebSockets DOM API<script type="text/javascript" charset="utf-8"> // Socket object var socket = new WebSocket('ws://some.host.com'); // Callbacks socket.onopen = function (evt) { alert('Socket connected: ' + evt.data) }; // Incoming server message socket.onmessage = function (evt) { alert( evt.data ) }; socket.onclose = function (evt) { alert('Connection terminated') // reconnect, etc. };</script>
Friday, 19 November 2010
WebSockets handshakeRequest
Response
GET /demo HTTP/1.1Host: example.comConnection: UpgradeSec-WebSocket-Key2: 12998 5 Y3 1 .P00Sec-WebSocket-Protocol: sampleUpgrade: WebSocketSec-WebSocket-Key1: 4 @1 46546xW%0l 1 5Origin: http://example.com
^n:ds[4U
HTTP/1.1 101 WebSocket Protocol HandshakeUpgrade: WebSocketConnection: UpgradeSec-WebSocket-Origin: http://example.comSec-WebSocket-Location: ws://example.com/demoSec-WebSocket-Protocol: sample
8jKS'y:G*Co,Wxa-
(draft 76)
Friday, 19 November 2010
"\x00Hello World\xff"
Mensajes
// Incoming server messagesocket.onmessage = function (evt) { alert( evt.data )};
// Send message to serversocket.send("Hello server, this is a new client");
Friday, 19 November 2010
(Ruby) WebSockets server
•Hablar WebSockets (handshake)
•Mantener conexiones abiertas
•Rendimiento
• Escalable
• Threads? Eventos?
Friday, 19 November 2010
EventMachine rubyeventmachine.com
require 'eventmachine'
module EchoServer def receive_data(data) send_data data end end
EventMachine::run { EventMachine::start_server 'localhost', 8080, EchoServer puts 'running echo server on 8080'}
Friday, 19 November 2010
EM-WebSocket github.com/igrigorik/em-websocket
EventMachine.run { EventMachine::WebSocket.start(:host=>'0.0.0.0',:port=>8080) do |socket| socket.onopen { # publish message to the client socket.send 'Websocket connection open' } socket.onmessage {|msg| # echo message to client socket.send "Received message: #{msg}" } end}
Friday, 19 November 2010
Multicast - subscribers...@channel = Channel.new...
socket.onopen { @channel.subscribe socket}
socket.onmessage { |msg| @channel.send_message msg}
socket.onclose { @channel.unsubscribe socket}
Friday, 19 November 2010
Multicast - subscribers# Serversocket.onopen { @channel.subscribe socket}
class Channel def initialize @sockets = [] end def subscribe( socket ) @sockets << socket end ...end
Friday, 19 November 2010
Multicast - channelclass Channel ... def subscribe( socket ) @sockets << socket end def send_message( msg ) @sockets.each do |socket| socket.send msg end end def unsubscribe( socket ) @sockets.delete socket endend
Friday, 19 November 2010
Multicast - ejemplo
var socket = new WebSocket('ws://localhost:8080');
socket.onmessage = function( evt ) {$('<li>')
.text(evt.data) .appendTo('#messages');}
<ul id="messages"> </ul>
HTML
Javascript
Friday, 19 November 2010
Multicast - ejemplo
github.com/ismasan/websockets_examples
Friday, 19 November 2010
Elige tu protocolo
STOMP CONNECTlogin: <username>passcode: <passcode>
<message from=”[email protected]/ruby” to=”[email protected]/ruby”><body>Hey Jane!</body>
</message>
XMPP
Your own (JSON?)
Friday, 19 November 2010
Formato personalizado
JSON
Friday, 19 November 2010
Formato personalizado
{“event”: “user_connected”,
{“name” : “Ismael”,“total_users” : 10
}
}
Event name
Custom data
“data”:
Friday, 19 November 2010
Formato personalizado
{“event”: “user_message”,
{“message” : “Hello!”,“date” : “23 2010 21:12:28”
}
}
“data”:
Friday, 19 November 2010
Javascript wrapper
var socket = new FancyWebSocket('ws://localhost:8080');
...
socket.bind( 'user_connected', function (user_data) { // Add user to screen $('#connected_users').append('<li>' + user_data.name + '</li>');});
socket.bind( 'user_message', function (msg_data) { // Add message to screen $('#messages').append('<li>' + msg_data.message + '</li>');});
Friday, 19 November 2010
// Broadcast message - jQuery example
$('form#user_input').submit(function () { var msg = $(this).find('input[name=message]').val(); socket.send( 'user_message', {name: 'Ismael', message: msg} ); return false;});
Javascript wrapper
{“event” : “user_message”,
{“name” : “Ismael”,“message” : “hello!”
}}
“data” :
Friday, 19 November 2010
Implementaciónvar FancyWebSocket = function(url){ var conn = new WebSocket(url);
var callbacks = {};
this.bind = function(event_name, callback){ callbacks[event_name] = callbacks[event_name] || []; callbacks[event_name].push(callback); };
this.send = function(event_name, event_data){ var payload = JSON.stringify({event:event_name, data: event_data}); conn.send( payload ); };
// dispatch to the right handlers conn.onmessage = function(evt){ var json = JSON.parse(evt.data) dispatch(json.event, json.data) };
conn.onclose = function(){dispatch('close',null)} conn.onopen = function(){dispatch('open',null)}
var dispatch = function(event_name, message){ var chain = callbacks[event_name]; if(typeof chain == 'undefined') return; // no callbacks for this event for(var i = 0; i < chain.length; i++){ chain[i]( message ) } }};
gist.github.com/299789
Friday, 19 November 2010
Implementación
var FancyWebSocket = function(url){
var conn = new WebSocket(url);
var callbacks = {};
this.bind = function(event_name, callback){ callbacks[event_name] = callbacks[event_name] || []; callbacks[event_name].push(callback); };
this.send = function(event_name, event_data){ var payload = JSON.stringify({event:event_name, data: event_data}); conn.send( payload ); };
// dispatch to the right handlers conn.onmessage = function(evt){ var json = JSON.parse(evt.data) dispatch(json.event, json.data) };
};
gist.github.com/299789
Friday, 19 November 2010
Ismael Celis
Implementaciónvar FancyWebSocket = function(url){ var conn = new WebSocket(url);
var callbacks = {};
this.bind = function(event_name, callback){ callbacks[event_name] = callbacks[event_name] || []; callbacks[event_name].push(callback); };
this.send = function(event_name, event_data){ var payload = JSON.stringify({event:event_name, data: event_data}); conn.send( payload ); };
// dispatch to the right handlers conn.onmessage = function(evt){ var json = JSON.parse(evt.data) dispatch(json.event, json.data) };
conn.onclose = function(){dispatch('close',null)} conn.onopen = function(){dispatch('open',null)}
var dispatch = function(event_name, message){ var chain = callbacks[event_name]; if(typeof chain == 'undefined') return; // no callbacks for this event for(var i = 0; i < chain.length; i++){ chain[i]( message ) } }};
gist.github.com/299789
Friday, 19 November 2010
// dispatch to the right handlers conn.onmessage = function(evt){ var json = JSON.parse(evt.data) dispatch(json.event, json.data) };
conn.onclose = function(){dispatch('close',null)} conn.onopen = function(){dispatch('open',null)}
var dispatch = function(event_name, message){ var chain = callbacks[event_name]; if(typeof chain == 'undefined') return; // no callbacks for this event for(var i = 0; i < chain.length; i++){ chain[i]( message ) } }};
Implementación
WebSocket
gist.github.com/299789
Friday, 19 November 2010
var FancyWebSocket = function(url){
// dispatch to the right handlers conn.onmessage = function(evt){ var json = JSON.parse(evt.data) dispatch(json.event, json.data) };
conn.onclose = function(){dispatch('close',null)} conn.onopen = function(){dispatch('open',null)}
var dispatch = function(event_name, message){ var chain = callbacks[event_name]; // no callbacks for this event if(typeof chain == 'undefined') return; for(var i = 0; i < chain.length; i++){ chain[i]( message ) } }};
Implementación gist.github.com/299789
Friday, 19 November 2010
socket.send( 'user_message', {name: 'Ismael', message: msg} );
Implementación
this.send = function(event_name, event_data){ var payload = JSON.stringify({event:event_name, data: event_data}); conn.send( payload ); // <= send JSON data to socket server return this;};
gist.github.com/299789
Friday, 19 November 2010
Multicast - datos JSON
github.com/ismasan/websockets_examples
Friday, 19 November 2010
Multicast - datos JSON
$('#canvas').mousedown(function () { drawing = true;}).mouseup(function () { drawing = false;}).mousemove(function (evt) { if(drawing) { var point = [evt.pageX, evt.pageY]; socket.send('mousemove', point); }});
Friday, 19 November 2010
Multicast - datos JSONvar ctx = document.getElementById('canvas').getContext('2d');ctx.lineWidth = 1;ctx.strokeStyle = '#ffffff';ctx.beginPath();ctx.moveTo(0, 0);
// Listen to other user's movessocket.bind('mousemove', function (point) { ctx.lineTo(point[0],point[1]); ctx.stroke();});
Friday, 19 November 2010
Panel de actividad
Friday, 19 November 2010
Panel Rails Rumble
Friday, 19 November 2010
Escalando
?Friday, 19 November 2010
pusherapp.com
Friday, 19 November 2010
pusherapp.com
Your appREST
Browsers
Websockets
Existing HTTP
Friday, 19 November 2010
pusherapp.com
Friday, 19 November 2010
pusherapp.com
<script src="http://js.pusherapp.com/1.6/pusher.min.js"></script>
<script type="text/javascript" charset="utf-8"> var socket = new Pusher('293d8ae77496e1fc053b'); </script>
Friday, 19 November 2010
pusherapp.com
var socket = new Pusher('293d8ae77496e1fc053b'); // Subscribe to channelsvar channel = socket.subscribe( 'test' ); channel.bind( 'new_message', function (data) { alert( data.message );})
Friday, 19 November 2010
pusherapp.com
// Subscribe to PRESENCE channelvar chat = socket.subscribe( 'presence-chat' ); // Listen to new memberschat.bind( 'pusher:member_added', function (member) { alert( member.user_data.name );})
Friday, 19 November 2010
require 'pusher'require 'sinatra'
post '/messages' do message = Message.create(params[:message]) Pusher['presence-chat'].trigger(:new_message, message.attributes) redirect '/messages'end
pusherapp.com
$ gem install pusher
Friday, 19 November 2010
pusherapp.com
github.com/
lifo/cramp
ismasan/websockets_examplesnewbamboo/rumbledash
blog.new-bamboo.co.ukblog.pusherapp.com
Friday, 19 November 2010
Tutorial
github.com/ismasan/pusher-chat-tutorial
Friday, 19 November 2010
Widgets
var chat = pusher.subscribe('presence-chat');
new Widgets.Messages( chat ); new Widgets.Members( chat );
new Widgets.SoundAlerts( chat );
Friday, 19 November 2010
Widgets
Widgets.Messages = function (chat) { /*------------------------------------------------------ Listen to messages -------------------------------------------------------*/ chat.bind( 'message', function (message) { $('<li>') .text(message.user + ' dice: ' + message.body) .appendTo('#messages'); }); }
// new Widgets.Messages( chat );
Friday, 19 November 2010
github.com/ismasan/pusher-chat-tutorial
pusherapp.com/demospusherapp.com/docs
Friday, 19 November 2010