websockets, ruby y pusher webprendedor 2010

44
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

Upload: ismael-celis

Post on 25-Dec-2014

857 views

Category:

Documents


1 download

DESCRIPTION

 

TRANSCRIPT

Page 1: Websockets, Ruby y Pusher Webprendedor 2010

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

Page 2: Websockets, Ruby y Pusher Webprendedor 2010

Polling

Long-polling

Web socket

websockets.org/about.html

HTML5 Web sockets

Friday, 19 November 2010

Page 3: Websockets, Ruby y Pusher Webprendedor 2010

Casos de uso

•Chat

•Aplicaciones financieras

• Juegos

•Presencia de usuarios

•Colaboración

•Notificaciones Tiempo Real

Friday, 19 November 2010

Page 4: Websockets, Ruby y Pusher Webprendedor 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

Page 5: Websockets, Ruby y Pusher Webprendedor 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

Page 6: Websockets, Ruby y Pusher Webprendedor 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

Page 7: Websockets, Ruby y Pusher Webprendedor 2010

(Ruby) WebSockets server

•Hablar WebSockets (handshake)

•Mantener conexiones abiertas

•Rendimiento

• Escalable

• Threads? Eventos?

Friday, 19 November 2010

Page 8: Websockets, Ruby y Pusher Webprendedor 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

Page 9: Websockets, Ruby y Pusher Webprendedor 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

Page 10: Websockets, Ruby y Pusher Webprendedor 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

Page 11: Websockets, Ruby y Pusher Webprendedor 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

Page 12: Websockets, Ruby y Pusher Webprendedor 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

Page 13: Websockets, Ruby y Pusher Webprendedor 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

Page 14: Websockets, Ruby y Pusher Webprendedor 2010

Multicast - ejemplo

github.com/ismasan/websockets_examples

Friday, 19 November 2010

Page 15: Websockets, Ruby y Pusher Webprendedor 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

Page 16: Websockets, Ruby y Pusher Webprendedor 2010

Formato personalizado

JSON

Friday, 19 November 2010

Page 17: Websockets, Ruby y Pusher Webprendedor 2010

Formato personalizado

{“event”: “user_connected”,

{“name” : “Ismael”,“total_users” : 10

}

}

Event name

Custom data

“data”:

Friday, 19 November 2010

Page 18: Websockets, Ruby y Pusher Webprendedor 2010

Formato personalizado

{“event”: “user_message”,

{“message” : “Hello!”,“date” : “23 2010 21:12:28”

}

}

“data”:

Friday, 19 November 2010

Page 19: Websockets, Ruby y Pusher Webprendedor 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

Page 20: Websockets, Ruby y Pusher Webprendedor 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

Page 21: Websockets, Ruby y Pusher Webprendedor 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

Page 22: Websockets, Ruby y Pusher Webprendedor 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

Page 23: Websockets, Ruby y Pusher Webprendedor 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

Page 24: Websockets, Ruby y Pusher Webprendedor 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

Page 25: Websockets, Ruby y Pusher Webprendedor 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

Page 26: Websockets, Ruby y Pusher Webprendedor 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

Page 27: Websockets, Ruby y Pusher Webprendedor 2010

Multicast - datos JSON

github.com/ismasan/websockets_examples

Friday, 19 November 2010

Page 28: Websockets, Ruby y Pusher Webprendedor 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

Page 29: Websockets, Ruby y Pusher Webprendedor 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

Page 30: Websockets, Ruby y Pusher Webprendedor 2010

Panel de actividad

Friday, 19 November 2010

Page 31: Websockets, Ruby y Pusher Webprendedor 2010

Panel Rails Rumble

Friday, 19 November 2010

Page 32: Websockets, Ruby y Pusher Webprendedor 2010

Escalando

?Friday, 19 November 2010

Page 33: Websockets, Ruby y Pusher Webprendedor 2010

pusherapp.com

Friday, 19 November 2010

Page 34: Websockets, Ruby y Pusher Webprendedor 2010

pusherapp.com

Your appREST

Browsers

Websockets

Existing HTTP

Friday, 19 November 2010

Page 35: Websockets, Ruby y Pusher Webprendedor 2010

pusherapp.com

Friday, 19 November 2010

Page 36: Websockets, Ruby y Pusher Webprendedor 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

Page 37: Websockets, Ruby y Pusher Webprendedor 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

Page 38: Websockets, Ruby y Pusher Webprendedor 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

Page 39: Websockets, Ruby y Pusher Webprendedor 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

Page 40: Websockets, Ruby y Pusher Webprendedor 2010

pusherapp.com

github.com/

lifo/cramp

ismasan/websockets_examplesnewbamboo/rumbledash

blog.new-bamboo.co.ukblog.pusherapp.com

Friday, 19 November 2010

Page 41: Websockets, Ruby y Pusher Webprendedor 2010

Tutorial

github.com/ismasan/pusher-chat-tutorial

Friday, 19 November 2010

Page 42: Websockets, Ruby y Pusher Webprendedor 2010

Widgets

var chat = pusher.subscribe('presence-chat');

new Widgets.Messages( chat ); new Widgets.Members( chat );

new Widgets.SoundAlerts( chat );

Friday, 19 November 2010

Page 43: Websockets, Ruby y Pusher Webprendedor 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