15

Websockets en la práctica 2

1May
en HTML5, Tutoriales, WebSockets

El artículo de hoy sobre websockets es una colaboración del estudiante de Yaicel Torres Garces.

WebSocket es una tecnología que proporciona un canal de comunicación bidireccional y full-duplex sobre un único socket TCP. Está diseñada para ser implementada en navegadores y servidores web, pero puede utilizarse por cualquier aplicación cliente/servidor. La API de WebSocket está siendo normalizada por el W3C, y el protocolo WebSocket, a su vez, está siendo normalizado por el IETF.

El WebSocket es una característica de HTML 5 para establecer conexiones de socket entre un navegador web y un servidor, una vez que la conexión ha sido establecida con el servidor, todos los datos WebSocket (frames) se envían directamente sobre un socket en lugar de respuesta HTTP habitual y peticiones.

Vamos a crear un sistema de chat sencillo como muestra la figura, utilizando esta tecnología  (HTML5 WebSocket y PHP).

chat1

Cliente WebSocket 

La aplicación WebSocket del lado del cliente es muy fácil, todo el código consta de unos métodos y eventos como lo muestra el código siguiente

 websocket = new WebSocket("ws://localhost:5800/server.php");
 websocket.onopen = function(evt) { /* escribir algo */ };
 websocket.onclose = function(evt) { /* escribir algo */ };
 websocket.onmessage = function(evt) { /* escribir algo*/ };
 websocket.onerror = function(evt) { /* escribir algo */ };
 websocket.send(message);
 websocket.close();

Para abrir la conexión de socket, simplemente llamamos new WebSocket (ws: / / URL del servidor), ya que WebSocket utiliza un protocolo diferente para las conexiones, utilizamos ws / en lugar de http://, seguido por el anfitrión, número de puerto y servidor:

chat2

Inmediatamente después de abrir la conexión, tenemos que fijar algunos controladores de eventos que nos permiten conocer el estado de la conectividad, los errores y los mensajes entrantes, para sus referencias:

  1. WebSocket(wsUri) — crea un nuevo objeto WebSocket.
  2. .onopen — El evento se produce cuando se establece la conexión.
  3. .onclose — El evento se produce cuando la conexión está cerrada.
  4. .onmessage — El evento se produce cuando el cliente recibe los datos del servidor.
  5. .onerror — El evento se produce cuando hay un error.
  6. .send(message) — Transmite datos a servidor utilizando una conexión abierta.
  7. .close() — Termina la conexión existente.

Como se explica en los ejemplos anteriores, se comienza creando un objeto WebSocket, adjuntando los controladores de eventos y luego utilizando el método websocket.send para enviar los datos. Puesto que estamos enviando una colección de valores de chat, como el nombre de usuario y mensaje, convertiremos nuestros datos a formato JSON antes de enviarlos al servidor.

Servidor WebSocket 

Ahora tenemos a nuestra página de chat en vivo listo para conectarse al servidor, pero también tenemos que crear un servidor WebSocket que se ejecuta de forma permanente (sin tiempos de espera).

PHP Socket
Básicamente nuestro servidor debe hacer lo siguiente.

  1. Abrir un socket.
  2. Enlazar a una dirección.
  3. Escuchar las conexiones entrantes.
  4. Aceptar conexiones.
  5. WebSocket Handshake.
  6. Tramas de datos Desenmascarar / Encode.

Abrir un socket:
Primero creamos un socket con socket_create ( int $domain , int $type , int $protocol ) de esta manera:


$socket = socket_create (AF_INET, SOCK_STREAM, SOL_TCP);

AF_INET:Protocolo basado en Internet IPv4. TCP y UDP son protocolos comunes de esta familia de protocolos.

SOCK_STREAM:Proporciona flujos de bytes orientados a conexión, secuenciados, fiables y full-duplex.

Si el protocolo deseado es TCP o UDP, también se pueden usar las constantes SOL_TCP, y SOL_UDP correspondientes.

Enlazar a una dirección:
Vincular el nombre dado en address al socket descrito por socket socket_bind ( resource$socket , string$address [, int$port = 0 ] ) , esto se tiene que hacer antes de establecer una conexión mediante socket_connect () o socket_listen ().


socket_bind ($socket, 'localhost');

Escuchar las conexiones entrantes:
Una vez creado el socket, configuramos nuestro servidor para que escuche la conexión entrante en ese socket.


socket_listen($socket);

Aceptar conexiones:
Esta función acepta conexiones entrantes.

 socket_accept ($socket);

Pueden bajar el ejemplo completo desde aquí. Para que el servidor comience a esperar conexiones deben ejecutar desde la consola:

$ php server.php
Etiquetado en:

15 Comentarios

  1. liusvel dice:

    Hola he intentado levantar el ejemplo que das en el articulo(modificandole claro el ip especifico para mi pc) , levanto el servidor bien , pero a la hora de enviar un mensaje no pincha , cual pudiese ser el error ??? , y gracias por este articulo tan interesante!!!

  2. kceres dice:

    hay un error en index.php …donde dice var wsUri = “ws://10.52.16.28:8080”; debe decir var wsUri = “ws://127.0.0.1:8080”;

    PD …sería mejor, para ver un funcionamiento real, por lo menos poder implementar un mini chat mas real, donde se pudiera seleccionar la persona con la que se va a chatear

    por lo demás, el ejemplo esta muy bien!

    saludos, kceres

  3. zico dice:

    Hay un módulo para NodeJS (socket.io) que está genial. Lo uso en mi tesis. Si puedo publicaré un artículo en el sitio de php sobre su uso. Saludos.

    • Yaicel dice:

      Es evidente que node es superior en este ambiente pero lo que se muestra aqui es solo un pequeño ejemplo del uso de websockets con php.

  4. Yosbel Marin dice:

    Una de las cosas que se deberían explicar por acá es como construir el “handshake”, hay un estándar para websocket.

    Saludos.

  5. Víctor Manuel dice:

    Fuese bueno que hicieran un proyecto que se intalara completamente ya funcional, casi un cms, con el cual se pudiese montar un servicio en si. Y explicar sus ventajas.

  6. zico dice:

    Si pudieran poner un ejemplo de envío de archivos usando este protocolo.

  7. Yo personalmente usoi Node.js es mejor. Hay 1000 + 1 librerias para WebSockets. Yo Aconsejo Socket.io y WS.

    Para Yunier, Erick y mis colegas de la UCI: Ya estoy pidiendo el reingreso en la carrera. Saludos Napster

  8. Dnis dice:

    caballero eso siempre me da disconect, alguna sugerencia,

  9. arisxs dice:

    eh intentado modificar el programa para que mande solamente datos desde el servidor al cliente,

    eh intentado modificar algunos parametros par quitar el siguinte
    while(socket_recv($changed_socket, $buf, 1024, 0) >= 1)
    {
    $received_text = unmask($buf); //unmask data
    $tst_msg = json_decode($received_text);
    y eso me envia el mensaje pero al actualizar la pagina o al abrir la pagina en una ventana nueva el mensaje se mulptiplica una infinidad de veces

    de igual manera si quito la parte del foreach($changed as $changed_socket)
    envia el mensaje pero la coneccion se cierra y con ello el programa

    si pudieran ayudarme se los agredeceria demasiado

    saludos

  10. David Chavez dice:

    hola estimado amigo:
    descargue tu ejemplo y me sale error al conectar al servidor tengo que hacer alguna configuracion mas.
    por favor ayudeme

  11. carla dice:

    Hola a todos, estoy actualizandome en el mundo de paginas web /php /javascript, pero al ver q esto es lo nuevo (websocket) no entiendo algo, hace como 15 años yo usaba esta forma de trabajo con winsockets en visual basic con app cliente/servidor por puertos yo enviaba/recibia data, mi pregunta es si ya esto de websocket se esta utilizando en las paginas web a nivel mundial hoy en dia?

  12. el llillo dice:

    Muchachos me interesa este tema,debo hacer una aplicacion web que monitoree servidores por lo cual debo esconder estos comandos bajo botones y graficas.si me pudieran orientar de como resolver este enigma atraves de la websocket.saludos.

Dejar un comentario

¿Eres humano? Entonces resuelve esta operación: * Límite de tiempo se agote. Por favor, recargar el CAPTCHA por favor.