SlideShare una empresa de Scribd logo
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
Web en Tiempo Real
XMPP, Websockets, et al.
¿Qué es XMPP?
                                         antesJabber
Extensible Messaging and Presence Protocol

   Envío de mensajes en tiempo real

          Codificados en XML

 Transportados sobre TCP y UDP (media)




           http://xmpp.org
¿Por qué XMPP?
                para la   Web
  HTTP
Half-duplex
 stateless
¿Por qué XMPP?
                        para la   Web
        HTTP
      Half-duplex
        stateless

c
s
    normal polling (AJAX)
c

s
    long polling (Comet)
¿Por qué XMPP?
                        para la   Web
        HTTP                 XMPP
      Half-duplex           Full-duplex
        stateless            stateful

c
s
    normal polling (AJAX)
c

s
    long polling (Comet)
¿Por qué XMPP?
                        para la        Web
        HTTP                      XMPP
      Half-duplex               Full-duplex
        stateless                 stateful

c
s                           c
    normal polling (AJAX)
c
                            s
                                conexión persistente
s
    long polling (Comet)
Arquitectura XMPP




       O’REILLY XMPP: The Definitive Guide
Arquitectura XMPP



Web (HTTP)             Mail (SMTP)




             XMPP
La red XMPP: Entidades

        Servidores
         Clientes
       Componentes
         Plugins
Servidores


          Enrutan mensajes
Hablan con clientes y otros servidores
  FOSS: Ejabberd, Openfire, Tigase
Clientes


   Humanos y robots

Protocolo cliente-servidor
Componentes

Extienden la funcionalidad del servidor

Tienen su propia identidad y dirección
    Se ejecutan fuera del mismo
Se comunican con un protocolo específico

        Ejemplo típico: Multichat
Plugins


Mismo propósito que los componentes

También tienen identidad y dirección
          No hay IPC              mayor rendimiento
Direccionamiento en XMPP

     JIDs: almenos uno por cada entidad

         local@dom.ain/resource
 it@miinterprete.appspotchat.com/adium
            Bare JID

                  Full JID
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>
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>
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>
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>
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
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
Tiempo real en La Web
Acercando XMPP a la Web
            Pre HTML 5

     Comunicación basada en HTTP

         AJAX & Long Polling

      Bidirectional-Streams over
         synchronous HTTP
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
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
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)
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)
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;
Web en tiempo real con
    Websockets
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)
<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>
<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>
<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>
<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>
<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>
<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>
<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>
Echo (single client)

require 'rubygems'
require 'eventmachine-websocket'

EventMachine::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
Multichat en 23LOC
require 'rubygems'
require 'eventmachine-websocket'

connections=[]
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
      end
end
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
Bilbiografía
Gracias
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

Más contenido relacionado

Similar a Real-time web

Conceptos acerca de Ajax
Conceptos acerca  de AjaxConceptos acerca  de Ajax
Conceptos acerca de Ajax
Alvaro Castillo
 
Introduccion Ajax V1.0
Introduccion Ajax V1.0Introduccion Ajax V1.0
Introduccion Ajax V1.0
Arnulfo Gomez
 
Conceptos Introductorios Del Web 2
Conceptos Introductorios Del Web 2Conceptos Introductorios Del Web 2
Conceptos Introductorios Del Web 2
Michelle Aguirre
 
Presentacion remobjects
Presentacion remobjectsPresentacion remobjects
Presentacion remobjects
mamcx
 
Servicios web
Servicios webServicios web
Servicios web
Emilio Sarabia
 
Aplicaciones Web
Aplicaciones WebAplicaciones Web
Aplicaciones Web
Gorka Prieto
 
Ajax
AjaxAjax
Ajax
ousli07
 
Opensouthcode: Microservicios sobre MEAN Stack
Opensouthcode: Microservicios sobre MEAN StackOpensouthcode: Microservicios sobre MEAN Stack
Opensouthcode: Microservicios sobre MEAN Stack
Pedro J. Molina
 
Microservicios sobre MEAN Stack
Microservicios sobre MEAN StackMicroservicios sobre MEAN Stack
Microservicios sobre MEAN Stack
Pedro J. Molina
 
SignalR y dispositivos móviles
SignalR y dispositivos móvilesSignalR y dispositivos móviles
SignalR y dispositivos móviles
Javier Suárez Ruiz
 
Semana 1 tecnologias web
Semana 1   tecnologias webSemana 1   tecnologias web
Semana 1 tecnologias web
INFOVIC
 
Ruby y las arquitecturas orientadas a servicios
Ruby y las arquitecturas orientadas a servicios Ruby y las arquitecturas orientadas a servicios
Ruby y las arquitecturas orientadas a servicios
Joaquín Salvachúa
 
01 Ext Js Introduccion
01 Ext Js   Introduccion01 Ext Js   Introduccion
01 Ext Js Introduccion
Mayer Horna
 
ASP.NET MVC Workshop Día 3
ASP.NET MVC Workshop Día 3ASP.NET MVC Workshop Día 3
ASP.NET MVC Workshop Día 3
Rodolfo Finochietti
 
Protocolo http
Protocolo httpProtocolo http
Protocolo http
Dani Gutiérrez Porset
 
Programación web con JSP
Programación web con JSPProgramación web con JSP
Programación web con JSP
ousli07
 
Generación de web sites dinámicos usando php
Generación de web sites dinámicos usando phpGeneración de web sites dinámicos usando php
Generación de web sites dinámicos usando php
Julio Alfredo Cauich Cauich
 
Servicios web Extendido_error perl
Servicios web Extendido_error perlServicios web Extendido_error perl
Servicios web Extendido_error perl
Octavio Izucar Martinez
 
Codemotion 2013 - Quiero tiempo real y lo quiero para ayer
Codemotion 2013 - Quiero tiempo real y lo quiero para ayerCodemotion 2013 - Quiero tiempo real y lo quiero para ayer
Codemotion 2013 - Quiero tiempo real y lo quiero para ayer
Iván López Martín
 
Protocol HTTP
Protocol HTTPProtocol HTTP

Similar a Real-time web (20)

Conceptos acerca de Ajax
Conceptos acerca  de AjaxConceptos acerca  de Ajax
Conceptos acerca de Ajax
 
Introduccion Ajax V1.0
Introduccion Ajax V1.0Introduccion Ajax V1.0
Introduccion Ajax V1.0
 
Conceptos Introductorios Del Web 2
Conceptos Introductorios Del Web 2Conceptos Introductorios Del Web 2
Conceptos Introductorios Del Web 2
 
Presentacion remobjects
Presentacion remobjectsPresentacion remobjects
Presentacion remobjects
 
Servicios web
Servicios webServicios web
Servicios web
 
Aplicaciones Web
Aplicaciones WebAplicaciones Web
Aplicaciones Web
 
Ajax
AjaxAjax
Ajax
 
Opensouthcode: Microservicios sobre MEAN Stack
Opensouthcode: Microservicios sobre MEAN StackOpensouthcode: Microservicios sobre MEAN Stack
Opensouthcode: Microservicios sobre MEAN Stack
 
Microservicios sobre MEAN Stack
Microservicios sobre MEAN StackMicroservicios sobre MEAN Stack
Microservicios sobre MEAN Stack
 
SignalR y dispositivos móviles
SignalR y dispositivos móvilesSignalR y dispositivos móviles
SignalR y dispositivos móviles
 
Semana 1 tecnologias web
Semana 1   tecnologias webSemana 1   tecnologias web
Semana 1 tecnologias web
 
Ruby y las arquitecturas orientadas a servicios
Ruby y las arquitecturas orientadas a servicios Ruby y las arquitecturas orientadas a servicios
Ruby y las arquitecturas orientadas a servicios
 
01 Ext Js Introduccion
01 Ext Js   Introduccion01 Ext Js   Introduccion
01 Ext Js Introduccion
 
ASP.NET MVC Workshop Día 3
ASP.NET MVC Workshop Día 3ASP.NET MVC Workshop Día 3
ASP.NET MVC Workshop Día 3
 
Protocolo http
Protocolo httpProtocolo http
Protocolo http
 
Programación web con JSP
Programación web con JSPProgramación web con JSP
Programación web con JSP
 
Generación de web sites dinámicos usando php
Generación de web sites dinámicos usando phpGeneración de web sites dinámicos usando php
Generación de web sites dinámicos usando php
 
Servicios web Extendido_error perl
Servicios web Extendido_error perlServicios web Extendido_error perl
Servicios web Extendido_error perl
 
Codemotion 2013 - Quiero tiempo real y lo quiero para ayer
Codemotion 2013 - Quiero tiempo real y lo quiero para ayerCodemotion 2013 - Quiero tiempo real y lo quiero para ayer
Codemotion 2013 - Quiero tiempo real y lo quiero para ayer
 
Protocol HTTP
Protocol HTTPProtocol HTTP
Protocol HTTP
 

Más de Miguel Fernández

Hierarchical taxonomy extraction
Hierarchical taxonomy extractionHierarchical taxonomy extraction
Hierarchical taxonomy extraction
Miguel Fernández
 
Yahoo! pipes
Yahoo! pipesYahoo! pipes
Yahoo! pipes
Miguel Fernández
 
Screen scraping
Screen scrapingScreen scraping
Screen scraping
Miguel Fernández
 
App engine
App engineApp engine
App engine
Miguel Fernández
 
Ruby intro
Ruby introRuby intro
Ruby intro
Miguel Fernández
 
Rails intro
Rails introRails intro
Rails intro
Miguel Fernández
 

Más de Miguel Fernández (6)

Hierarchical taxonomy extraction
Hierarchical taxonomy extractionHierarchical taxonomy extraction
Hierarchical taxonomy extraction
 
Yahoo! pipes
Yahoo! pipesYahoo! pipes
Yahoo! pipes
 
Screen scraping
Screen scrapingScreen scraping
Screen scraping
 
App engine
App engineApp engine
App engine
 
Ruby intro
Ruby introRuby intro
Ruby intro
 
Rails intro
Rails introRails intro
Rails intro
 

Último

Desarrollo de habilidades de pensamiento (2).pdf
Desarrollo de habilidades de pensamiento (2).pdfDesarrollo de habilidades de pensamiento (2).pdf
Desarrollo de habilidades de pensamiento (2).pdf
samuelvideos
 
absorcion de gases y practicas de laboratorios
absorcion de gases y practicas de laboratoriosabsorcion de gases y practicas de laboratorios
absorcion de gases y practicas de laboratorios
JuanAlvarez413513
 
Estructuras Básicas_ Conceptos Basicos De Programacion.pdf
Estructuras Básicas_ Conceptos Basicos De Programacion.pdfEstructuras Básicas_ Conceptos Basicos De Programacion.pdf
Estructuras Básicas_ Conceptos Basicos De Programacion.pdf
IsabellaRubio6
 
TECLADO ERGONÓMICO Y PANTALLAS TACTILES - GESTIÓN INTEGRAL EDUCATIVA
TECLADO ERGONÓMICO Y PANTALLAS TACTILES - GESTIÓN INTEGRAL EDUCATIVATECLADO ERGONÓMICO Y PANTALLAS TACTILES - GESTIÓN INTEGRAL EDUCATIVA
TECLADO ERGONÓMICO Y PANTALLAS TACTILES - GESTIÓN INTEGRAL EDUCATIVA
LilibethEstupian
 
algebra de boole teoria.pdf texto guia.1
algebra de boole teoria.pdf texto guia.1algebra de boole teoria.pdf texto guia.1
algebra de boole teoria.pdf texto guia.1
yuki22434
 
Catalogo Buzones BTV Amado Salvador Distribuidor Oficial Valencia
Catalogo Buzones BTV Amado Salvador Distribuidor Oficial ValenciaCatalogo Buzones BTV Amado Salvador Distribuidor Oficial Valencia
Catalogo Buzones BTV Amado Salvador Distribuidor Oficial Valencia
AMADO SALVADOR
 
Computacion cuántica y sus ventajas y desventajas
Computacion cuántica y sus ventajas y desventajasComputacion cuántica y sus ventajas y desventajas
Computacion cuántica y sus ventajas y desventajas
sofiahuarancabellido
 
Estructuras Básicas_Tecnología_Grado10-7.pdf
Estructuras Básicas_Tecnología_Grado10-7.pdfEstructuras Básicas_Tecnología_Grado10-7.pdf
Estructuras Básicas_Tecnología_Grado10-7.pdf
cristianrb0324
 
Estructuras básicas_ conceptos de programación (1).docx
Estructuras básicas_ conceptos de programación  (1).docxEstructuras básicas_ conceptos de programación  (1).docx
Estructuras básicas_ conceptos de programación (1).docx
SamuelRamirez83524
 
MANUAL DEL DECODIFICADOR DVB S2. PARA VSAT
MANUAL DEL DECODIFICADOR DVB  S2. PARA VSATMANUAL DEL DECODIFICADOR DVB  S2. PARA VSAT
MANUAL DEL DECODIFICADOR DVB S2. PARA VSAT
Ing. Julio Iván Mera Casas
 
Catalogo General Electrodomesticos Teka Distribuidor Oficial Amado Salvador V...
Catalogo General Electrodomesticos Teka Distribuidor Oficial Amado Salvador V...Catalogo General Electrodomesticos Teka Distribuidor Oficial Amado Salvador V...
Catalogo General Electrodomesticos Teka Distribuidor Oficial Amado Salvador V...
AMADO SALVADOR
 
Informe DATA & IA 2024 Primera encuesta sobre el uso de IA en las empresas pe...
Informe DATA & IA 2024 Primera encuesta sobre el uso de IA en las empresas pe...Informe DATA & IA 2024 Primera encuesta sobre el uso de IA en las empresas pe...
Informe DATA & IA 2024 Primera encuesta sobre el uso de IA en las empresas pe...
alejandromanuelve
 
Conceptos básicos de programación 10-5.pdf
Conceptos básicos de programación 10-5.pdfConceptos básicos de programación 10-5.pdf
Conceptos básicos de programación 10-5.pdf
ValeriaAyala48
 
Projecte Iniciativa TIC 2024 HPE. inCV.pdf
Projecte Iniciativa TIC 2024 HPE. inCV.pdfProjecte Iniciativa TIC 2024 HPE. inCV.pdf
Projecte Iniciativa TIC 2024 HPE. inCV.pdf
Festibity
 
Semana 10_MATRIZ IPER_UPN_ADM_03.06.2024
Semana 10_MATRIZ IPER_UPN_ADM_03.06.2024Semana 10_MATRIZ IPER_UPN_ADM_03.06.2024
Semana 10_MATRIZ IPER_UPN_ADM_03.06.2024
CesarPazosQuispe
 
Catalogo Cajas Fuertes BTV Amado Salvador Distribuidor Oficial
Catalogo Cajas Fuertes BTV Amado Salvador Distribuidor OficialCatalogo Cajas Fuertes BTV Amado Salvador Distribuidor Oficial
Catalogo Cajas Fuertes BTV Amado Salvador Distribuidor Oficial
AMADO SALVADOR
 
Manual de soporte y mantenimiento de equipo de cómputo
Manual de soporte y mantenimiento de equipo de cómputoManual de soporte y mantenimiento de equipo de cómputo
Manual de soporte y mantenimiento de equipo de cómputo
doctorsoluciones34
 
Desarrollo de habilidades de pensamiento.docx
Desarrollo de habilidades de pensamiento.docxDesarrollo de habilidades de pensamiento.docx
Desarrollo de habilidades de pensamiento.docx
ortizjuanjose591
 
IA en entornos rurales aplicada a la viticultura
IA en entornos rurales aplicada a la viticulturaIA en entornos rurales aplicada a la viticultura
IA en entornos rurales aplicada a la viticultura
Miguel Rebollo
 
TODO SOBRE LA INFORMÁTICA, HISTORIA, ¿QUE ES?, IMPORTANCIA Y CARACTERISTICAS....
TODO SOBRE LA INFORMÁTICA, HISTORIA, ¿QUE ES?, IMPORTANCIA Y CARACTERISTICAS....TODO SOBRE LA INFORMÁTICA, HISTORIA, ¿QUE ES?, IMPORTANCIA Y CARACTERISTICAS....
TODO SOBRE LA INFORMÁTICA, HISTORIA, ¿QUE ES?, IMPORTANCIA Y CARACTERISTICAS....
bendezuperezjimena
 

Último (20)

Desarrollo de habilidades de pensamiento (2).pdf
Desarrollo de habilidades de pensamiento (2).pdfDesarrollo de habilidades de pensamiento (2).pdf
Desarrollo de habilidades de pensamiento (2).pdf
 
absorcion de gases y practicas de laboratorios
absorcion de gases y practicas de laboratoriosabsorcion de gases y practicas de laboratorios
absorcion de gases y practicas de laboratorios
 
Estructuras Básicas_ Conceptos Basicos De Programacion.pdf
Estructuras Básicas_ Conceptos Basicos De Programacion.pdfEstructuras Básicas_ Conceptos Basicos De Programacion.pdf
Estructuras Básicas_ Conceptos Basicos De Programacion.pdf
 
TECLADO ERGONÓMICO Y PANTALLAS TACTILES - GESTIÓN INTEGRAL EDUCATIVA
TECLADO ERGONÓMICO Y PANTALLAS TACTILES - GESTIÓN INTEGRAL EDUCATIVATECLADO ERGONÓMICO Y PANTALLAS TACTILES - GESTIÓN INTEGRAL EDUCATIVA
TECLADO ERGONÓMICO Y PANTALLAS TACTILES - GESTIÓN INTEGRAL EDUCATIVA
 
algebra de boole teoria.pdf texto guia.1
algebra de boole teoria.pdf texto guia.1algebra de boole teoria.pdf texto guia.1
algebra de boole teoria.pdf texto guia.1
 
Catalogo Buzones BTV Amado Salvador Distribuidor Oficial Valencia
Catalogo Buzones BTV Amado Salvador Distribuidor Oficial ValenciaCatalogo Buzones BTV Amado Salvador Distribuidor Oficial Valencia
Catalogo Buzones BTV Amado Salvador Distribuidor Oficial Valencia
 
Computacion cuántica y sus ventajas y desventajas
Computacion cuántica y sus ventajas y desventajasComputacion cuántica y sus ventajas y desventajas
Computacion cuántica y sus ventajas y desventajas
 
Estructuras Básicas_Tecnología_Grado10-7.pdf
Estructuras Básicas_Tecnología_Grado10-7.pdfEstructuras Básicas_Tecnología_Grado10-7.pdf
Estructuras Básicas_Tecnología_Grado10-7.pdf
 
Estructuras básicas_ conceptos de programación (1).docx
Estructuras básicas_ conceptos de programación  (1).docxEstructuras básicas_ conceptos de programación  (1).docx
Estructuras básicas_ conceptos de programación (1).docx
 
MANUAL DEL DECODIFICADOR DVB S2. PARA VSAT
MANUAL DEL DECODIFICADOR DVB  S2. PARA VSATMANUAL DEL DECODIFICADOR DVB  S2. PARA VSAT
MANUAL DEL DECODIFICADOR DVB S2. PARA VSAT
 
Catalogo General Electrodomesticos Teka Distribuidor Oficial Amado Salvador V...
Catalogo General Electrodomesticos Teka Distribuidor Oficial Amado Salvador V...Catalogo General Electrodomesticos Teka Distribuidor Oficial Amado Salvador V...
Catalogo General Electrodomesticos Teka Distribuidor Oficial Amado Salvador V...
 
Informe DATA & IA 2024 Primera encuesta sobre el uso de IA en las empresas pe...
Informe DATA & IA 2024 Primera encuesta sobre el uso de IA en las empresas pe...Informe DATA & IA 2024 Primera encuesta sobre el uso de IA en las empresas pe...
Informe DATA & IA 2024 Primera encuesta sobre el uso de IA en las empresas pe...
 
Conceptos básicos de programación 10-5.pdf
Conceptos básicos de programación 10-5.pdfConceptos básicos de programación 10-5.pdf
Conceptos básicos de programación 10-5.pdf
 
Projecte Iniciativa TIC 2024 HPE. inCV.pdf
Projecte Iniciativa TIC 2024 HPE. inCV.pdfProjecte Iniciativa TIC 2024 HPE. inCV.pdf
Projecte Iniciativa TIC 2024 HPE. inCV.pdf
 
Semana 10_MATRIZ IPER_UPN_ADM_03.06.2024
Semana 10_MATRIZ IPER_UPN_ADM_03.06.2024Semana 10_MATRIZ IPER_UPN_ADM_03.06.2024
Semana 10_MATRIZ IPER_UPN_ADM_03.06.2024
 
Catalogo Cajas Fuertes BTV Amado Salvador Distribuidor Oficial
Catalogo Cajas Fuertes BTV Amado Salvador Distribuidor OficialCatalogo Cajas Fuertes BTV Amado Salvador Distribuidor Oficial
Catalogo Cajas Fuertes BTV Amado Salvador Distribuidor Oficial
 
Manual de soporte y mantenimiento de equipo de cómputo
Manual de soporte y mantenimiento de equipo de cómputoManual de soporte y mantenimiento de equipo de cómputo
Manual de soporte y mantenimiento de equipo de cómputo
 
Desarrollo de habilidades de pensamiento.docx
Desarrollo de habilidades de pensamiento.docxDesarrollo de habilidades de pensamiento.docx
Desarrollo de habilidades de pensamiento.docx
 
IA en entornos rurales aplicada a la viticultura
IA en entornos rurales aplicada a la viticulturaIA en entornos rurales aplicada a la viticultura
IA en entornos rurales aplicada a la viticultura
 
TODO SOBRE LA INFORMÁTICA, HISTORIA, ¿QUE ES?, IMPORTANCIA Y CARACTERISTICAS....
TODO SOBRE LA INFORMÁTICA, HISTORIA, ¿QUE ES?, IMPORTANCIA Y CARACTERISTICAS....TODO SOBRE LA INFORMÁTICA, HISTORIA, ¿QUE ES?, IMPORTANCIA Y CARACTERISTICAS....
TODO SOBRE LA INFORMÁTICA, HISTORIA, ¿QUE ES?, IMPORTANCIA Y CARACTERISTICAS....
 

Real-time web

  • 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. Web en Tiempo Real XMPP, Websockets, et al.
  • 3. ¿Qué es XMPP? antesJabber Extensible Messaging and Presence Protocol Envío de mensajes en tiempo real Codificados en XML Transportados sobre TCP y UDP (media) http://xmpp.org
  • 4. ¿Por qué XMPP? para la Web HTTP Half-duplex stateless
  • 5. ¿Por qué XMPP? para la Web HTTP Half-duplex stateless c s normal polling (AJAX) c s long polling (Comet)
  • 6. ¿Por qué XMPP? para la Web HTTP XMPP Half-duplex Full-duplex stateless stateful c s normal polling (AJAX) c s long polling (Comet)
  • 7. ¿Por qué XMPP? para la Web HTTP XMPP Half-duplex Full-duplex stateless stateful c s c normal polling (AJAX) c s conexión persistente s long polling (Comet)
  • 8. Arquitectura XMPP O’REILLY XMPP: The Definitive Guide
  • 9. Arquitectura XMPP Web (HTTP) Mail (SMTP) XMPP
  • 10. La red XMPP: Entidades Servidores Clientes Componentes Plugins
  • 11. Servidores Enrutan mensajes Hablan con clientes y otros servidores FOSS: Ejabberd, Openfire, Tigase
  • 12. Clientes Humanos y robots Protocolo cliente-servidor
  • 13. Componentes Extienden la funcionalidad del servidor Tienen su propia identidad y dirección Se ejecutan fuera del mismo Se comunican con un protocolo específico Ejemplo típico: Multichat
  • 14. Plugins Mismo propósito que los componentes También tienen identidad y dirección No hay IPC mayor rendimiento
  • 15. Direccionamiento en XMPP JIDs: almenos uno por cada entidad local@dom.ain/resource it@miinterprete.appspotchat.com/adium Bare JID Full JID
  • 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. 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. 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. 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. 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. 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. Tiempo real en La Web
  • 23. Acercando XMPP a la Web Pre HTML 5 Comunicación basada en HTTP AJAX & Long Polling Bidirectional-Streams over synchronous HTTP
  • 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. 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. 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. 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. 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. Web en tiempo real con Websockets
  • 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. <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. <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. <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. <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. <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. <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. <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. Echo (single client) require 'rubygems' require 'eventmachine-websocket' EventMachine::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. Multichat en 23LOC require 'rubygems' require 'eventmachine-websocket' connections=[] 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 end end
  • 40.
  • 41. 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
  • 44. 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