Websockets, Ruby y Pusher Webprendedor 2010

Preview:

DESCRIPTION

 

Citation preview

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=”john@server.com/ruby” to=”jane@server.com/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