Crear un chat en tiempo real con CodeIgniter y WebSocket: guía práctica
Una guía práctica para crear un chat en tiempo real con CodeIgniter 4 y la librería PHP Ratchet, explicando la arquitectura, el servidor WebSocket y la conexión con el frontend.
Si alguna vez has usado un chat online —desde WhatsApp Web hasta una ventana de soporte en directo— habrás notado que los mensajes aparecen al instante, sin necesidad de recargar la página. Esto es posible gracias a los WebSocket, una tecnología que permite al navegador y al servidor intercambiar datos en tiempo real mediante una única conexión que permanece abierta, en lugar de abrir una nueva para cada solicitud como hace el HTTP clásico.
En esta guía construiremos un chat sencillo en tiempo real usando CodeIgniter, un framework PHP ligero y muy utilizado, combinado con una librería PHP dedicada a gestionar conexiones WebSocket. El objetivo es entender la arquitectura y los pasos clave, para poder luego adaptar el proyecto a tus propias necesidades.
Por qué el HTTP clásico no basta para un chat
El protocolo HTTP, el que usa el navegador para cargar páginas web, funciona por solicitudes: el cliente (el navegador) pide algo al servidor, el servidor responde y la conexión se cierra. Para un chat este enfoque sería incómodo: el navegador tendría que preguntar constantemente "¿hay mensajes nuevos?" cada pocos segundos (una técnica llamada polling), con el consiguiente desperdicio de recursos y retrasos perceptibles.
Los WebSocket resuelven el problema abriendo un canal de comunicación bidireccional que permanece activo: una vez establecida la conexión, tanto el servidor como el navegador pueden enviar mensajes en cualquier momento, sin tener que repetir la solicitud desde cero. Es el mismo principio que usan las apps de mensajería, las notificaciones en vivo de los paneles de administración y los juegos multijugador en el navegador.
La arquitectura: dos procesos distintos
Un detalle importante antes de empezar: CodeIgniter, como la mayoría de los frameworks PHP tradicionales, está pensado para gestionar solicitudes HTTP "clásicas" a través de un servidor web como Apache o Nginx con PHP-FPM. Ese modelo de ejecución de PHP no está diseñado para mantener abiertas miles de conexiones persistentes, que es exactamente lo que necesita un servidor WebSocket.
La solución más habitual, y la que usaremos aquí, es separar las dos responsabilidades:
- La aplicación CodeIgniter sigue encargándose de todo lo demás: páginas, autenticación, guardado del historial de mensajes en la base de datos, API REST.
- Un proceso PHP independiente, lanzado desde la línea de comandos y siempre en ejecución, gestiona únicamente las conexiones WebSocket mediante una librería dedicada (en nuestro caso Ratchet, una de las librerías PHP más utilizadas para este propósito).
Los dos procesos se comunican entre sí cuando es necesario (por ejemplo, para guardar un mensaje en la base de datos), pero siguen siendo independientes: si el servidor WebSocket se reinicia, el sitio principal sigue funcionando con normalidad.
Requisitos previos
- PHP 8.2 o superior: el requisito mínimo de las versiones recientes de CodeIgniter 4 (la 4.7.4, la última disponible en el momento de escribir esto, también es compatible con PHP 8.5).
- Composer, el gestor de dependencias de PHP, para instalar CodeIgniter y las librerías necesarias.
- Un proyecto CodeIgniter 4 ya creado (con
composer create-project codeigniter4/appstarter nombre-proyecto). - La extensión PHP
socketsactivada, necesaria para que funcione el servidor WebSocket.
Paso 1: instalar la librería WebSocket
Dentro de la carpeta del proyecto CodeIgniter, instalamos Ratchet a través de Composer:
composer require cboden/ratchet
Ratchet es una librería que implementa el protocolo WebSocket en PHP apoyándose en ReactPHP, un framework de programación asíncrona: permite que nuestro script PHP gestione muchas conexiones a la vez sin bloquearse esperando a cada una.
Paso 2: escribir la lógica del chat
Creamos una clase que implementa la interfaz MessageComponentInterface de Ratchet. Esta clase define qué ocurre cuando un usuario se conecta, envía un mensaje o se desconecta. Un ejemplo simplificado, guardado por ejemplo en app/Libraries/ChatServer.php:
class ChatServer implements MessageComponentInterface {
protected $clients;
public function __construct() { $this->clients = new \SplObjectStorage; }
public function onOpen($conn) { $this->clients->attach($conn); }
public function onMessage($from, $msg) {
foreach ($this->clients as $client) {
if ($from !== $client) { $client->send($msg); }
}
}
public function onClose($conn) { $this->clients->detach($conn); }
public function onError($conn, $e) { $conn->close(); }
}
En la práctica: cuando llega un mensaje de un usuario (onMessage), lo retransmitimos a todos los demás usuarios conectados excepto a quien lo envió. Esta es la lógica básica de un chat grupal; a partir de aquí se pueden añadir salas separadas, nombres de usuario, mensajes privados y guardado en base de datos.
Paso 3: iniciar el servidor WebSocket
Se necesita un pequeño script que se ejecuta desde la terminal, separado del flujo normal de CodeIgniter, por ejemplo chat_server.php en la raíz del proyecto:
$server = IoServer::factory(new HttpServer(new WsServer(new ChatServer())), 8080);
$server->run();
Al ejecutarlo con php chat_server.php, el servidor quedará escuchando en el puerto 8080, listo para aceptar conexiones WebSocket. En producción, este script debe mantenerse activo con una herramienta como Supervisor, que lo reinicia automáticamente si falla, y colocarse detrás de un proxy inverso (Nginx o Apache) que gestione el certificado SSL, para exponer la conexión segura wss:// en lugar del simple ws://.
Paso 4: conectar el frontend
En la vista de CodeIgniter de la página de chat, bastan unas pocas líneas de JavaScript nativo para conectarse al servidor WebSocket, sin necesidad de librerías externas:
const socket = new WebSocket('wss://tusitio.com:8080');
socket.onmessage = (event) => { /* mostrar el mensaje recibido en la página */ };
document.getElementById('enviar').onclick = () => { socket.send(textoMensaje); };
A partir de aquí se puede enriquecer la interfaz con un framework CSS como Bootstrap (muy usado junto a CodeIgniter) para que el chat se vea mejor, o integrar la autenticación ya gestionada por la aplicación CodeIgniter, enviando un token en el momento de la conexión para verificar quién está escribiendo.
Una alternativa lista para usar
Quien prefiera no escribir el servidor WebSocket desde cero puede valorar paquetes de Composer pensados específicamente para integrarse con los comandos spark de CodeIgniter 4, como takielias/codeigniter4-websocket, que ofrece una estructura ya preparada con callbacks para autenticación, salas y temporizadores, que se inicia con un comando dedicado en lugar de un script separado. Resulta útil para prototipar rápido, aunque sigue basándose en la misma librería Ratchet descrita antes.
Conclusión
Añadir un chat en tiempo real a un proyecto CodeIgniter no significa abandonar el framework: simplemente consiste en añadirle un pequeño proceso PHP dedicado, construido sobre una librería como Ratchet, que se encarga solo de la parte "siempre conectada". Una vez entendido este esquema —una aplicación clásica por un lado, un servidor WebSocket persistente por otro— se puede extender la misma lógica a notificaciones en vivo, paneles que se actualizan automáticamente o cualquier otra función que requiera comunicación instantánea entre servidor y navegador.
Fuentes oficiales
Compartir
¿Cuál es tu reacción?
Me gusta
0
No me gusta
0
Me encanta
0
Divertido
0
Enfadado
0
Triste
0
¡Vaya!
0