Universidad de Oviedo   Programa de extensión universitaria     CLOUD COMPUTING.DESARROLLO DE APLICACIONES Y        MINERÍ...
Web en Tiempo RealXMPP, Websockets, et al.
¿Qué es XMPP?                                         antesJabberExtensible Messaging and Presence Protocol   Envío de men...
¿Por qué XMPP?                para la   Web  HTTPHalf-duplex stateless
¿Por qué XMPP?                        para la   Web        HTTP      Half-duplex        statelesscs    normal polling (AJA...
¿Por qué XMPP?                        para la   Web        HTTP                 XMPP      Half-duplex           Full-duple...
¿Por qué XMPP?                        para la        Web        HTTP                      XMPP      Half-duplex           ...
Arquitectura XMPP       O’REILLY XMPP: The Definitive Guide
Arquitectura XMPPWeb (HTTP)             Mail (SMTP)             XMPP
La red XMPP: Entidades        Servidores         Clientes       Componentes         Plugins
Servidores          Enrutan mensajesHablan con clientes y otros servidores  FOSS: Ejabberd, Openfire, Tigase
Clientes   Humanos y robotsProtocolo cliente-servidor
ComponentesExtienden la funcionalidad del servidorTienen su propia identidad y dirección    Se ejecutan fuera del mismoSe ...
PluginsMismo propósito que los componentesTambién tienen identidad y dirección          No hay IPC              mayor rend...
Direccionamiento en XMPP     JIDs: almenos uno por cada entidad         local@dom.ain/resource it@miinterprete.appspotchat...
XMPP Stanzas<stream:stream>    <iq type="get">        <query xmlns="jabber:iq:roster"/>    </iq>    <presence/>    <messag...
XMPP Stanzas<stream:stream>    <iq type="get">        <query xmlns="jabber:iq:roster"/>    </iq>    <presence/>    <messag...
XMPP Stanzas<stream:stream>    <iq type="get">        <query xmlns="jabber:iq:roster"/>        Dame mis contactos    </iq>...
XMPP Stanzas<stream:stream>    <iq type="get">        <query xmlns="jabber:iq:roster"/>        Dame mis contactos    </iq>...
XMPP Stanzas<stream:stream>    <iq type="get">        <query xmlns="jabber:iq:roster"/>        Dame mis contactos    </iq>...
XMPP Stanzas<stream:stream>    <iq type="get">        <query xmlns="jabber:iq:roster"/>        Dame mis contactos    </iq>...
Tiempo real en La Web
Acercando XMPP a la Web            Pre HTML 5     Comunicación basada en HTTP         AJAX & Long Polling      Bidirection...
AJAX & Long Polling  AJAX (muestreo frecuente)                                     Comet (Long Polling)setInterval(functio...
BOSH, XMPP sobre HTTP    Flujos bidireccionales sobre HTTP síncrono      Usa pares de petición-respuesta para simular Requ...
HTML5 Websockets                          HTML 5                        WebSockets          To enable Web applications to ...
HTML5 Websockets                             HTML 5                           WebSockets             To enable Web applica...
El contrato Websocket[Constructor(in DOMString url, in optional DOMString protocols)][Constructor(in DOMString url, in opt...
Web en tiempo real con    Websockets
Event Machine                                     à-la node.js (javascript) y twisted (python)              Framework I/O ...
<html>                         Nuestro cliente  <head>    <script src=jquery.min.js></script>    <script>    function WebS...
<html>                         Nuestro cliente  <head>    <script src=jquery.min.js></script>    <script>    function WebS...
<html>                         Nuestro cliente  <head>    <script src=jquery.min.js></script>    <script>    function WebS...
<html>                         Nuestro cliente  <head>    <script src=jquery.min.js></script>    <script>    function WebS...
<html>                         Nuestro cliente  <head>    <script src=jquery.min.js></script>    <script>    function WebS...
<html>                         Nuestro cliente  <head>    <script src=jquery.min.js></script>    <script>    function WebS...
<html>                         Nuestro cliente  <head>    <script src=jquery.min.js></script>    <script>    function WebS...
Echo (single client)require rubygemsrequire eventmachine-websocketEventMachine::WebSocket.start(:host => "0.0.0.0", :port ...
Multichat en 23LOCrequire rubygemsrequire eventmachine-websocketconnections=[]indexes={}EventMachine::WebSocket.start(:hos...
Conclusiones• Hastala aparición de HTML5, XMPP tenía unas expectativas muy altas como alternativa a Comet.• Sinembargo, se...
Bilbiografía
Gracias
Universidad de Oviedo   Programa de extensión universitaria     CLOUD COMPUTING.DESARROLLO DE APLICACIONES Y        MINERÍ...
Real-time web
Upcoming SlideShare
Loading in...5
×

Real-time web

1,206

Published on

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
1,206
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
9
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Real-time web

  1. 1. Universidad de Oviedo Programa de extensión universitaria CLOUD COMPUTING.DESARROLLO DE APLICACIONES Y MINERÍA WEB Miguel Fernández Fernández miguelff@innova.uniovi.es
  2. 2. Web en Tiempo RealXMPP, Websockets, et al.
  3. 3. ¿Qué es XMPP? antesJabberExtensible Messaging and Presence Protocol Envío de mensajes en tiempo real Codificados en XML Transportados sobre TCP y UDP (media) http://xmpp.org
  4. 4. ¿Por qué XMPP? para la Web HTTPHalf-duplex stateless
  5. 5. ¿Por qué XMPP? para la Web HTTP Half-duplex statelesscs normal polling (AJAX)cs long polling (Comet)
  6. 6. ¿Por qué XMPP? para la Web HTTP XMPP Half-duplex Full-duplex stateless statefulcs normal polling (AJAX)cs long polling (Comet)
  7. 7. ¿Por qué XMPP? para la Web HTTP XMPP Half-duplex Full-duplex stateless statefulcs c normal polling (AJAX)c s conexión persistentes long polling (Comet)
  8. 8. Arquitectura XMPP O’REILLY XMPP: The Definitive Guide
  9. 9. Arquitectura XMPPWeb (HTTP) Mail (SMTP) XMPP
  10. 10. La red XMPP: Entidades Servidores Clientes Componentes Plugins
  11. 11. Servidores Enrutan mensajesHablan con clientes y otros servidores FOSS: Ejabberd, Openfire, Tigase
  12. 12. Clientes Humanos y robotsProtocolo cliente-servidor
  13. 13. ComponentesExtienden la funcionalidad del servidorTienen su propia identidad y dirección Se ejecutan fuera del mismoSe comunican con un protocolo específico Ejemplo típico: Multichat
  14. 14. PluginsMismo propósito que los componentesTambién tienen identidad y dirección No hay IPC mayor rendimiento
  15. 15. Direccionamiento en XMPP JIDs: almenos uno por cada entidad local@dom.ain/resource it@miinterprete.appspotchat.com/adium Bare JID Full JID
  16. 16. XMPP Stanzas<stream:stream> <iq type="get"> <query xmlns="jabber:iq:roster"/> </iq> <presence/> <message to="bar@otherside.com" from="foo@oneside.com/adium" type="chat"> <body>Tomamos algo?</body> </message> <presence type="unavailable"/></stream:stream>
  17. 17. XMPP Stanzas<stream:stream> <iq type="get"> <query xmlns="jabber:iq:roster"/> </iq> <presence/> <message to="bar@otherside.com" from="foo@oneside.com/adium" type="chat"> <body>Tomamos algo?</body> </message> <presence type="unavailable"/></stream:stream>
  18. 18. XMPP Stanzas<stream:stream> <iq type="get"> <query xmlns="jabber:iq:roster"/> Dame mis contactos </iq> <presence/> <message to="bar@otherside.com" from="foo@oneside.com/adium" type="chat"> <body>Tomamos algo?</body> </message> <presence type="unavailable"/></stream:stream>
  19. 19. XMPP Stanzas<stream:stream> <iq type="get"> <query xmlns="jabber:iq:roster"/> Dame mis contactos </iq> <presence/> Estoy online <message to="bar@otherside.com" from="foo@oneside.com/adium" type="chat"> <body>Tomamos algo?</body> </message> <presence type="unavailable"/></stream:stream>
  20. 20. XMPP Stanzas<stream:stream> <iq type="get"> <query xmlns="jabber:iq:roster"/> Dame mis contactos </iq> <presence/> Estoy online <message to="bar@otherside.com" from="foo@oneside.com/adium" type="chat"> <body>Tomamos algo?</body> </message> <presence type="unavailable"/></stream:stream> Dile a bar que si tomamos algo
  21. 21. XMPP Stanzas<stream:stream> <iq type="get"> <query xmlns="jabber:iq:roster"/> Dame mis contactos </iq> <presence/> Estoy online <message to="bar@otherside.com" from="foo@oneside.com/adium" type="chat"> <body>Tomamos algo?</body> </message> <presence type="unavailable"/></stream:stream> Dile a bar que si Ya no estoy disponible tomamos algo
  22. 22. Tiempo real en La Web
  23. 23. Acercando XMPP a la Web Pre HTML 5 Comunicación basada en HTTP AJAX & Long Polling Bidirectional-Streams over synchronous HTTP
  24. 24. AJAX & Long Polling AJAX (muestreo frecuente) Comet (Long Polling)setInterval(function(){ function load(){ // pedimos cada 500 milisegundos esperando cambio $.ajax({ url: /my/page, success: function(){ $.ajax({ url: /my/page, success: function(data){} }); // abrimos la conexión durante 20 segundos}, 500); }, complete: load, timeout: 20000 }); } Latencia (200ms/petición) Reducción dramática de latencia Muchas peticiones no recogeran cambios Mucho más eficiente Se genera mucho tráfico
  25. 25. BOSH, XMPP sobre HTTP Flujos bidireccionales sobre HTTP síncrono Usa pares de petición-respuesta para simular Requiere de un proxy que dirija los stanzas al servidor XMPP HTTP/1.1 200 OK Content-Type: text/xml; charset=utf-8 Content-Length: 483 <body xmpp:version=1.0 authid=ServerStreamID xmlns=http://jabber.org/protocol/httpbind xmlns:xmpp=urn:xmpp:xbosh xmlns:stream=http://etherx.jabber.org/streams> <stream:features> <mechanisms xmlns=urn:ietf:params:xml:ns:xmpp-sasl> <mechanism>SCRAM-SHA-1</mechanism> <mechanism>PLAIN</mechanism> </mechanisms> </stream:features> </body> http://xmpp.org/extensions/xep-0206.html
  26. 26. HTML5 Websockets HTML 5 WebSockets To enable Web applications to maintain bidirectional communications with server-side processes, this specification introduces the WebSocket interface. Gecko 2.0b4 (24/08/2010) (Firefox 4 Nighties)Soportado en: Webkit 333 (Safari 4, Chrome >4)
  27. 27. HTML5 Websockets HTML 5 WebSockets To enable Web applications to maintain bidirectional communications with server-side processes, this specification introduces the WebSocket interface. c s conexión persistente Gecko 2.0b4 (24/08/2010) (Firefox 4 Nighties)Soportado en: Webkit 333 (Safari 4, Chrome >4)
  28. 28. El contrato Websocket[Constructor(in DOMString url, in optional DOMString protocols)][Constructor(in DOMString url, in optional DOMString[] protocols)]interface WebSocket { readonly attribute DOMString url; ws://services.com/service // ready state const unsigned short CONNECTING = 0; const unsigned short OPEN = 1; const unsigned short CLOSING = 2; const unsigned short CLOSED = 3; readonly attribute unsigned short readyState; estado de readonly attribute unsigned long bufferedAmount; la conexión // networking attribute Function onopen; attribute Function onmessage; Recepción de eventos attribute Function onerror; attribute Function onclose; readonly attribute DOMString protocol; void send(in DOMString data); Envío de mensajes void close();};WebSocket implements EventTarget;
  29. 29. Web en tiempo real con Websockets
  30. 30. Event Machine à-la node.js (javascript) y twisted (python) Framework I/O dirigida por eventos Implementa el patrón Reactor Corre sobre ruby Muy útil para crear aplicaciones servidor eventmachine (0.12.10)http://rubyeventmachine.com/ eventmachine-websocket (0.1.0)
  31. 31. <html> Nuestro cliente <head> <script src=jquery.min.js></script> <script> function WebSocketAdapter(url){ this.ws=new WebSocket(url); this.ws.onmessage = function(evt) {$("#msg").append("<p>"+evt.data+"</p>");}; this.ws.onclose = function() { alert("socket cerrado"); }; this.ws.onopen = function() { alert("conectado..."); }; this.send=function(msg) {this.ws.send(msg);} } var ws; $(document).ready(function(){ ws=new WebSocketAdapter("ws://localhost:8080/"); }); </script> </head> <body> <form> Enviar al servidor: <input id="texto" type="text" value="hola mundo!"></input> <input id="enviar" type="button" value="enviar" onclick="ws.send($(#texto).val())"/> </form> <div id="msg"></div> </body></html>
  32. 32. <html> Nuestro cliente <head> <script src=jquery.min.js></script> <script> function WebSocketAdapter(url){ this.ws=new WebSocket(url); this.ws.onmessage = function(evt) {$("#msg").append("<p>"+evt.data+"</p>");}; this.ws.onclose = function() { alert("socket cerrado"); }; this.ws.onopen = function() { alert("conectado..."); }; this.send=function(msg) {this.ws.send(msg);} } var ws; $(document).ready(function(){ ws=new WebSocketAdapter("ws://localhost:8080/"); }); </script> </head> <body> <form> Enviar al servidor: <input id="texto" type="text" value="hola mundo!"></input> <input id="enviar" type="button" value="enviar" onclick="ws.send($(#texto).val())"/> </form> <div id="msg"></div> </body></html>
  33. 33. <html> Nuestro cliente <head> <script src=jquery.min.js></script> <script> function WebSocketAdapter(url){ this.ws=new WebSocket(url); this.ws.onmessage = function(evt) {$("#msg").append("<p>"+evt.data+"</p>");}; this.ws.onclose = function() { alert("socket cerrado"); }; this.ws.onopen = function() { alert("conectado..."); }; this.send=function(msg) {this.ws.send(msg);} } var ws; $(document).ready(function(){ ws=new WebSocketAdapter("ws://localhost:8080/"); }); </script> </head> <body> <form> Enviar al servidor: <input id="texto" type="text" value="hola mundo!"></input> <input id="enviar" type="button" value="enviar" onclick="ws.send($(#texto).val())"/> </form> <div id="msg"></div> </body></html>
  34. 34. <html> Nuestro cliente <head> <script src=jquery.min.js></script> <script> function WebSocketAdapter(url){ this.ws=new WebSocket(url); this.ws.onmessage = function(evt) {$("#msg").append("<p>"+evt.data+"</p>");}; this.ws.onclose = function() { alert("socket cerrado"); }; this.ws.onopen = function() { alert("conectado..."); }; this.send=function(msg) {this.ws.send(msg);} } var ws; $(document).ready(function(){ ws=new WebSocketAdapter("ws://localhost:8080/"); }); </script> </head> <body> <form> Enviar al servidor: <input id="texto" type="text" value="hola mundo!"></input> <input id="enviar" type="button" value="enviar" onclick="ws.send($(#texto).val())"/> </form> <div id="msg"></div> </body></html>
  35. 35. <html> Nuestro cliente <head> <script src=jquery.min.js></script> <script> function WebSocketAdapter(url){ this.ws=new WebSocket(url); this.ws.onmessage = function(evt) {$("#msg").append("<p>"+evt.data+"</p>");}; this.ws.onclose = function() { alert("socket cerrado"); }; this.ws.onopen = function() { alert("conectado..."); }; this.send=function(msg) {this.ws.send(msg);} } var ws; $(document).ready(function(){ ws=new WebSocketAdapter("ws://localhost:8080/"); }); </script> </head> <body> <form> Enviar al servidor: <input id="texto" type="text" value="hola mundo!"></input> <input id="enviar" type="button" value="enviar" onclick="ws.send($(#texto).val())"/> </form> <div id="msg"></div> </body></html>
  36. 36. <html> Nuestro cliente <head> <script src=jquery.min.js></script> <script> function WebSocketAdapter(url){ this.ws=new WebSocket(url); this.ws.onmessage = function(evt) {$("#msg").append("<p>"+evt.data+"</p>");}; this.ws.onclose = function() { alert("socket cerrado"); }; this.ws.onopen = function() { alert("conectado..."); }; this.send=function(msg) {this.ws.send(msg);} } var ws; $(document).ready(function(){ ws=new WebSocketAdapter("ws://localhost:8080/"); }); </script> </head> <body> <form> Enviar al servidor: <input id="texto" type="text" value="hola mundo!"></input> <input id="enviar" type="button" value="enviar" onclick="ws.send($(#texto).val())"/> </form> <div id="msg"></div> </body></html>
  37. 37. <html> Nuestro cliente <head> <script src=jquery.min.js></script> <script> function WebSocketAdapter(url){ this.ws=new WebSocket(url); this.ws.onmessage = function(evt) {$("#msg").append("<p>"+evt.data+"</p>");}; this.ws.onclose = function() { alert("socket cerrado"); }; this.ws.onopen = function() { alert("conectado..."); }; this.send=function(msg) {this.ws.send(msg);} } var ws; $(document).ready(function(){ ws=new WebSocketAdapter("ws://localhost:8080/"); }); </script> </head> <body> <form> Enviar al servidor: <input id="texto" type="text" value="hola mundo!"></input> <input id="enviar" type="button" value="enviar" onclick="ws.send($(#texto).val())"/> </form> <div id="msg"></div> </body></html>
  38. 38. Echo (single client)require rubygemsrequire eventmachine-websocketEventMachine::WebSocket.start(:host => "0.0.0.0", :port => 8080) do |con| con.on_open { con.send "Cliente conectado"} con.on_message { |msg| con.send msg.reverse } con.on_close { puts "Cliente desconectado" }end
  39. 39. Multichat en 23LOCrequire rubygemsrequire eventmachine-websocketconnections=[]indexes={}EventMachine::WebSocket.start(:host => "0.0.0.0", :port => 8080) do |con| con.on_open do indexes[con]=connections.size+1 con.send "<p class="highlight">Eres el cliente #{indexes[con]}<p>" connections.each{ |c| c.send "<p class="highlight">El cliente #{indexes[con]} ha entrado en la sala<p>" } connections << con end con.on_message do |msg| connections.each{ |c| c.send "<p><span class="cliente">Cliente #{indexes[con]}:</span> #{msg}</p>" } end con.on_close do c.send "<p class="highlight">Has abandonado la sala</p>" connections.delete con indexes.delete con endend
  40. 40. Conclusiones• Hastala aparición de HTML5, XMPP tenía unas expectativas muy altas como alternativa a Comet.• Sinembargo, se han cancelado muchos servicios XMPP para el consumo de datos en tiempo real (Twitter firehose API)• Websocket se presenta como una alternativa más simple y elegante para la implementación de servicios Web de tiempo real• XMPP no pierde fuerza para mensajería instantánea
  41. 41. Bilbiografía
  42. 42. Gracias
  43. 43. Universidad de Oviedo Programa de extensión universitaria CLOUD COMPUTING.DESARROLLO DE APLICACIONES Y MINERÍA WEB Miguel Fernández Fernández miguelff@innova.uniovi.es
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×