Notificaciones PHP en tiempo real con Redis y WebSockets

Resumen: guía práctica para enviar notificaciones en tiempo real desde PHP usando Redis como bus de mensajes y WebSockets para entrega instantánea. Incluye ejemplo mínimo, buenas prácticas y checklist de despliegue.

Introducción

Las notificaciones en tiempo real son fundamentales para la experiencia de usuario moderna. En vez de pollings periódicos, una combinación de Redis (Pub/Sub o Streams) y un servidor WebSocket permite entregar mensajes al instante desde PHP.

Prerrequisitos

  • PHP con soporte para ejecución de procesos permanentes (p. ej. Workerman, Swoole o Ratchet)
  • Redis (instancia accesible desde el servidor WebSocket)
  • Cliente Redis para PHP (Predis o phpredis) y composer
  • Clientes Web que soporten WebSockets y lógica de reconexión

Desarrollo

La arquitectura básica separa responsabilidades: la aplicación PHP publicará eventos en Redis; un proceso WebSocket suscrito a Redis retransmitirá esos mensajes a los clientes conectados.

Procedimiento

Pasos esenciales:

  1. Publicar un evento en Redis desde la app PHP cuando ocurre la acción (por ejemplo, comentario nuevo).
  2. El proceso WebSocket está suscrito al canal Redis y recibe el evento.
  3. El proceso WebSocket envía el payload a los clientes conectados (filtrando por usuario o canal si aplica).
  4. El cliente maneja el mensaje (mostrar notificación, solicitar detalles, marcar como leído, etc.).

Ejemplo mínimo de servidor WebSocket en PHP usando Workerman y Predis (suscripción a Redis y broadcast a conexiones activas).

<?php
use Workerman\Worker;
use Predis\Client as RedisClient;

require 'vendor/autoload.php';

$ws = new Worker("websocket://0.0.0.0:8080");
$ws->count = 1;

$redis = new RedisClient();

$ws->onWorkerStart = function() use ($ws, $redis) {
    $pubsub = $redis->pubSubLoop();
    $pubsub->subscribe('notifications');
    foreach ($pubsub as $message) {
        if ($message->kind === 'message') {
            foreach ($ws->connections as $connection) {
                $connection->send($message->payload);
            }
        }
    }
};

Worker::runAll();
Lenguaje del código: PHP (php)

Este proceso mantiene una conexión permanente a Redis y distribuye cada mensaje recibido a todas las conexiones WebSocket. En producción conviene no enviar todo el payload a todos los clientes: filtrar por canal/usuario.

Ejemplo de publicación de un evento desde la aplicación PHP usando Predis.

<?php
use Predis\Client as RedisClient;

$redis = new RedisClient();

$event = json_encode([
    'type' => 'comment_created',
    'user_id' => 42,
    'data' => ['id' => 123, 'excerpt' => 'Nuevo comentario']
]);

$redis->publish('notifications', $event);
Lenguaje del código: PHP (php)

En el ejemplo anterior publicamos en un canal genérico ‘notifications’. Para evitar sobre-broadcasting, use canales por usuario o por topic (p. ej. notifications:user:42).

Ejemplos

Cliente JavaScript: conexión WebSocket básica con reconexión y manejo de mensajes ligeros (solo resumen; adapte según su app).

function createSocket(url) {
  let ws;
  let retry = 1000;

  function connect() {
    ws = new WebSocket(url);

    ws.onopen = () => {
      retry = 1000; // reset backoff
      console.log('WS connected');
    };

    ws.onmessage = (ev) => {
      const msg = JSON.parse(ev.data);
      // manejar evento: mostrar notificación o solicitar detalles
      console.log('evento', msg);
    };

    ws.onclose = () => {
      console.log('WS closed, reconnecting in', retry);
      setTimeout(connect, retry);
      retry = Math.min(30000, retry * 2);
    };

    ws.onerror = (err) => {
      console.error('WS error', err);
      ws.close();
    };
  }

  connect();
  return () => ws && ws.close();
}

// uso
const stop = createSocket('wss://example.com:8080');
Lenguaje del código: JavaScript (javascript)

Consejo: mantenga los payloads ligeros. Enviar solo el ID del evento o un resumen reduce latencia y consumo de ancho de banda.

Redis + WebSockets transforman un backend PHP tradicional en un canal de notificaciones cercano a tiempo real, sin necesidad de reescrituras completas.

Checklist

  1. Usar canales por usuario o topic para evitar sobre-broadcast.
  2. Autenticar y autorizar suscripciones (gateway o tokens JWT).
  3. Implementar reconexión y reintentos en cliente.
  4. Considerar Redis Streams si necesita persistencia y replay de mensajes.
  5. Monitoreo del proceso WebSocket y alertas para reinicio automático.
  6. Limitar tamaño del payload y evitar enviar datos sensibles por el socket.

Conclusión

Combinar Redis y WebSockets permite a aplicaciones PHP ofrecer notificaciones instantáneas sin depender de polling. El patrón reduce latencia y escala bien si se aplica filtrado por canales, autenticación y manejo de fallos.

Empiece con un prototipo mínimo (un proceso WebSocket suscrito a Redis) y evolucione a Streams, balanceo y autenticación según las necesidades de producción.

Comments

Deja un comentario

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