En esta guía crearemos una aplicación de chat básica. No requiere casi ningún conocimiento previo básico de Node.JS o Socket.IO, por lo que es ideal para usuarios de todos los niveles de conocimiento.

Introducción

Escribir una aplicación de chat con pilas de aplicaciones web populares como LAMP (PHP) ha sido tradicionalmente muy difícil. Implica sondear el servidor para detectar cambios, realizar un seguimiento de las marcas de tiempo y es mucho más lento de lo que debería ser.

Los sockets han sido tradicionalmente la solución alrededor de la cual se diseñan la mayoría de los sistemas de chat en tiempo real, proporcionando un canal de comunicación bidireccional entre un cliente y un servidor.

Esto significa que el servidor puede enviar mensajes a los clientes. Siempre que escriba un mensaje de chat, la idea es que el servidor lo reciba y lo envíe a todos los demás clientes conectados.

El framework web

El primer objetivo es configurar una página web HTML simple que sirva un formulario y una lista de mensajes. Vamos a utilizar el framework web Node.JS express para este fin. Asegúrese de que Node.JS está instalado.

Primero vamos a crear un archivo de manifiesto package.json que describa nuestro proyecto. Te recomiendo que lo coloques en un directorio vacío dedicado (llamaré mi chat-example ).

  { 
  "nombre" : "socket-chat-example" , 
  "versión" : "0.0.1" , 
  "description" : "mi primera aplicación socket.io" , 
  "dependencias" : {} 
  }

Ahora, para rellenar fácilmente las dependencies con las cosas que necesitamos, usaremos npm install --save :

  npm instalar --save express@4.15.2

Ahora que Express está instalado, podemos crear un archivo index.js que configurará nuestra aplicación.

  var app = require ( 'express' ) (); 
  var http = require ( 'http' ) .Server (aplicación); 

  app.get ( '/' , función ( req, res ) { 
  res.send ( '<h1> Hello world </h1>' ); 
  }); 

  http.listen ( 3000 , función (   ) { 
  console .log ( 'escuchar en *: 3000' ); 
  });

Esto se traduce en lo siguiente:

  • Express inicializa la app para que sea un controlador de funciones que puede suministrar a un servidor HTTP (como se ve en la línea 2).
  • Definimos un controlador de ruta / que se llama cuando ingresamos a nuestro sitio web.
  • Hacemos que el servidor http escuche en el puerto 3000.

Si ejecuta node index.js debería ver lo siguiente:

Una consola que dice que el servidor ha comenzado a escuchar en el puerto 3000

Y si apunta su navegador a http://localhost:3000 :

Un navegador que muestra un gran 'Hola mundo'

Sirviendo HTML

Hasta ahora, en index.js llamamos res.send y le pasamos una cadena HTML. Nuestro código sería muy confuso si pusiéramos allí el código HTML de toda nuestra aplicación. En su lugar, vamos a crear un archivo index.html y servirlo.

Vamos a refactorizar nuestro controlador de ruta para usar sendFile en sendFile lugar:

  app.get ( '/' , función ( req, res ) { 
  res.sendFile (__ dirname + '/index.html' ); 
  });

Y rellene index.html con lo siguiente:

  <! doctype html> 
  < html > 
  < cabeza > 
  < título > Socket.IO chat </ título > 
  < estilo >  
  * {margen: 0;  relleno: 0;  tamaño de caja: caja de borde;  } 
  body {font: 13px Helvetica, Arial;  } 
  formulario {fondo: # 000;  relleno: 3px;  posición: fijo  abajo: 0;  ancho: 100%;  } 
  entrada de formulario {borde: 0;  relleno: 10px;  ancho: 90%;  margen derecho: .5%;  } 
  botón de formulario {ancho: 9%;  fondo: rgb (130, 224, 255);  frontera: ninguna;  relleno: 10px;  } 
  #messages {list-style-type: none;  margen: 0;  relleno: 0;  } 
  #messages li {padding: 5px 10px;  } 
  #messages li: nth-child (impar) {background: #eee;  } 
       </ estilo > 
  </ cabeza > 
  < cuerpo > 
  < ul id = "mensajes" > </ ul > 
  < form action = "" > 
  < input id = "m" autocomplete = "off" /> < button > Send </ button > 
  </ form > 
  </ cuerpo > 
  </ html >

Si reinicia el proceso (presionando Control + C y ejecutando nuevamente el node index ) y actualiza la página, debería verse así:

Un navegador que muestra una entrada y un botón 'Enviar'

Integración de Socket.IO

Socket.IO se compone de dos partes:

  • Un servidor que se integra con (o se monta en) el servidor HTTP Node.JS : socket.io
  • Una biblioteca cliente que se carga en el lado del navegador: socket.io-client

Durante el desarrollo, socket.io sirve el cliente automáticamente para nosotros, como veremos, por lo que por ahora solo tenemos que instalar un módulo:

  npm instalar --save socket.io

Eso instalará el módulo y agregará la dependencia a package.json . Ahora editemos index.js para agregarlo:

  var app = require ( 'express' ) (); 
  var http = require ( 'http' ) .Server (aplicación); 
  var io = require ( 'socket.io' ) (http); 

  app.get ( '/' , función ( req, res ) { 
  res.sendFile (__ dirname + '/index.html' ); 
  }); 

  io.on ( 'conexión' , función ( socket ) { 
  consola .log ( 'un usuario conectado' ); 
  }); 

  http.listen ( 3000 , función (   ) { 
  console .log ( 'escuchar en *: 3000' ); 
  });

Observe que inicializo una nueva instancia de socket.io al pasar el objeto http (el servidor HTTP). Luego escucho el evento de connection para los sockets entrantes y lo registro en la consola.

Ahora en index.html agrego el siguiente fragmento de código antes del </body> :

  < script src = "/socket.io/socket.io.js" >   </ script > 
  < script >  
  var socket = io (); 
   </ script >

Eso es todo lo que se necesita para cargar el socket.io-client , que expone un io global, y luego conectarse.

Tenga en cuenta que no estoy especificando ninguna URL cuando llamo a io() , ya que por defecto intenta conectarse al host que sirve la página.

Si ahora vuelve a cargar el servidor y el sitio web, debería ver la impresión de la consola “un usuario conectado”.

Intenta abrir varias pestañas y verás varios mensajes:

Una consola que muestra varios mensajes, indicando que algunos usuarios se han conectado.

Cada socket también dispara un evento de disconnect especial:

  io.on ( 'conexión' , función ( socket ) { 
  consola .log ( 'un usuario conectado' ); 
  socket.on ( 'desconectar' , función (   ) { 
  consola .log ( 'usuario desconectado' ); 
  }); 
  });

Luego, si actualiza una pestaña varias veces, puede verla en acción:

Una consola que muestra varios mensajes, lo que indica que algunos usuarios se han conectado y desconectado

Emitiendo eventos

La idea principal detrás de Socket.IO es que puede enviar y recibir cualquier evento que desee, con la información que desee. Cualquier objeto que pueda codificarse como JSON funcionará, y los datos binarios también son compatibles.

Hagámoslo de modo que cuando el usuario escriba un mensaje, el servidor lo reciba como un evento de chat message . La sección del script en index.html ahora debería tener el siguiente aspecto:

  < script src = "/socket.io/socket.io.js" >   </ script > 
  < script src = "https://code.jquery.com/jquery-1.11.1.js" >   </ script > 
  < script >  
  $ ( función (   ) { 
  var socket = io (); 
  $ ( 'form' ) .submit ( function (   ) { 
  socket.emit ( 'mensaje de chat' , $ ( '#m' ) .val ()); 
  $ ( '#m' ) .val ( '' ); 
  devuelve falso 
  }); 
  }); 
   </ script >

Y en index.js imprimimos el evento de chat message :

  io.on ( 'conexión' , función ( socket ) { 
  socket.on ( 'mensaje de chat' , función ( msg ) { 
  consola .log ( 'mensaje:' + msg); 
  }); 
  });

El resultado debería ser como el siguiente video:

Radiodifusión

El siguiente objetivo es que emitamos el evento desde el servidor al resto de usuarios.

Para enviar un evento a todos, Socket.IO nos da el io.emit :

  io.emit ( 'algún evento' , { para : 'todos' });

Si desea enviar un mensaje a todos excepto a un determinado socket, tenemos el indicador de broadcast :

  io.on ( 'conexión' , función ( socket ) { 
  socket.broadcast.emit ( 'hi' ); 
  });

En este caso, por simplicidad, enviaremos el mensaje a todos, incluido el remitente.

  io.on ( 'conexión' , función ( socket ) { 
  socket.on ( 'mensaje de chat' , función ( msg ) { 
  io.emit ( 'mensaje de chat' , msg); 
  }); 
  });

Y en el lado del cliente, cuando capturemos un evento de chat message , lo incluiremos en la página. El código total de JavaScript del lado del cliente ahora equivale a:

  < script >  
  $ ( función (   ) { 
  var socket = io (); 
  $ ( 'form' ) .submit ( function (   ) { 
  socket.emit ( 'mensaje de chat' , $ ( '#m' ) .val ()); 
  $ ( '#m' ) .val ( '' ); 
  devuelve falso 
  }); 
  socket.on ( 'mensaje de chat' , función ( msg ) { 
  $ ( '#messages' ) .append ($ ( '<li>' ) .text (msg)); 
  }); 
  }); 
   </ script >

¡Y eso completa nuestra aplicación de chat, en aproximadamente 20 líneas de código! Esto es lo que parece:

Deberes

Aquí hay algunas ideas para mejorar la aplicación:

  • Transmita un mensaje a los usuarios conectados cuando alguien se conecta o desconecta.
  • Añadir soporte para los apodos.
  • No envíe el mismo mensaje al usuario que lo envió él mismo. En su lugar, agregue el mensaje directamente tan pronto como presiona entrar.
  • Agregue la funcionalidad “{user} is typing”.
  • Mostrar quién está en línea.
  • Añadir mensajería privada.
  • ¡Comparte tus mejoras!

Obteniendo este ejemplo

Puedes encontrarlo en GitHub aquí .

  git clone https://github.com/socketio/chat-example.git
¿Caído un error? Editar esta página en GitHub
 

Solución para Cannot GET /503.html

RewriteCond %{REQUEST_URI} ^/socket.io [NC]
RewriteCond %{QUERY_STRING} transport=websocket [NC]
RewriteRule /(.*) ws://localhost:3000/$1 [P,L]
DO NOT REMOVE. CLOUDLINUX PASSENGER CONFIGURATION BEGIN
DirectoryIndex
RewriteRule ^/?socket.io https://chat.dinadiesel.com:3000/socket.io/socket.io.js [P,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
PassengerAppRoot “/home/dinadiesel/chat”
PassengerBaseURI “/chat”
PassengerNodejs “/home/dinadiesel/nodevenv/chat/9/bin/node”
PassengerAppType node
PassengerStartupFile index.js
RewriteEngine on
DO NOT REMOVE. CLOUDLINUX PASSENGER CONFIGURATION END

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *