Un WebSocket es una conexión persistente y bidireccional entre cliente y servidor que permite a ambos lados enviar mensajes en el instante en que ocurren. HTTP hizo la web preguntando; los WebSockets la hicieron viva escuchando — un upgrade estandarizado (RFC 6455) convierte una solicitud en un canal abierto, y todo lo que es tiempo real en la web — chat, presencia, tickers, cursores colaborativos — viaja sobre él.
Puntos clave
| Pregunta | Respuesta |
|---|---|
| Qué es | Una conexión persistente y full-duplex — push del servidor, envío del cliente, la misma tubería |
| vs. HTTP | Request-response stateless vs. canal abierto con estado |
| El handshake | GET de HTTP + Upgrade → 101 Switching Protocols → frames |
| Reglas de producción | Siempre wss://, heartbeats + reconexión con backoff, planifica el fan-out |
| La capa superior | Sincronización en tiempo real — consultas y estado sobre el socket, no mensajes crudos |
Cómo funciona el handshake de upgrade de WebSocket (HTTP 101)
GET /chat HTTP/1.1 ← empieza como HTTP común
Host: example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
HTTP/1.1 101 Switching Protocols ← y aquí deja de ser HTTP
Upgrade: websocket
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
# Desde ahora: frames diminutos (2–14 bytes de overhead), en ambas direcciones,
# vs ~500+ bytes de headers por cada poll HTTP individual.
La mayoría de las aplicaciones no debería programar a mano lo que viene después — el idioma de producción es una capa de tiempo real gestionada donde el socket, los heartbeats y la reconexión son código de otra persona:
// JavaScript / Node.js — Back4app JS SDK (Live Query over WebSockets)
// One WebSocket, managed for you: connect, subscribe, reconnect
const query = new Parse.Query('Message');
query.equalTo('room', 'general');
const subscription = await query.subscribe(); // wss:// under the hood
subscription.on('create', (msg) => appendToChat(msg));
subscription.on('open', () => setStatus('live'));
// Later: subscription.unsubscribe(); // Flutter / Dart — Back4app Flutter SDK (Live Query over WebSockets)
// One WebSocket, managed for you: connect, subscribe, reconnect
final liveQuery = LiveQuery();
final query = QueryBuilder<ParseObject>(ParseObject('Message'))
..whereEqualTo('room', 'general');
final sub = await liveQuery.client.subscribe(query); // wss:// under the hood
sub.on(LiveQueryEvent.create, (msg) => appendToChat(msg)); // iOS / Swift — Back4app Swift SDK (Live Query over WebSockets)
// One WebSocket, managed for you: connect, subscribe, reconnect
let query = Message.query("room" == "general")
let subscription = query.subscribeCallback // wss:// under the hood
subscription?.handleEvent { _, event in
if case .created(let msg) = event { appendToChat(msg) }
} // Android / Kotlin — Back4app Android SDK (Live Query over WebSockets)
// One WebSocket, managed for you: connect, subscribe, reconnect
val client = ParseLiveQueryClient.Factory.getClient()
val query = ParseQuery.getQuery<ParseObject>("Message")
query.whereEqualTo("room", "general")
val handling = client.subscribe(query) // wss:// under the hood
handling.handleEvent(SubscriptionHandling.Event.CREATE) { _, msg ->
appendToChat(msg)
} WebSockets vs. todo lo demás que mueve datos
| Transporte | Dirección | Cómo funciona | Ideal para |
|---|---|---|---|
| Polling | El cliente pregunta repetidamente | Solicitud completa por chequeo | Solo fallback legacy |
| Long polling | El cliente pregunta, el servidor demora | Una solicitud pendiente por mensaje | Fallback de compatibilidad |
| SSE | Solo servidor → cliente | HTTP en streaming, reconexión automática | Feeds, tickers, notificaciones |
| WebSocket | Ambos sentidos | TCP persistente con upgrade | Chat, juegos, colaboración, sync |
| WebRTC | Peer ↔ peer | Canales UDP de media/datos | Llamadas, video — señalizados vía WebSockets |
Operar sockets en producción
Cuatro conceptos cargan el peso operativo. Afinidad de sesión: las conexiones tienen estado, así que los balanceadores de carga deben mantener a cada cliente anclado a su nodo. Fan-out: transmitir un mensaje a diez mil suscriptores repartidos en muchos nodos requiere un backplane de pub/sub entre servidores — el mensaje viaja de servidor a servidor antes de viajar de servidor a cliente. Backpressure: a un teléfono lento en una mala red no se le puede permitir acumular mensajes sin límite en la memoria de tu servidor; descarta, fusiona o desconecta. Vitalidad: los frames ping/pong más los heartbeats de aplicación detectan conexiones medio muertas, y los clientes se reconectan con backoff exponencial y jitter, y luego vuelven a suscribir su estado — el paso que las implementaciones ingenuas olvidan. Nada de esto es exótico; todo esto es la razón por la que “solo abrimos un socket” se convierte en una decisión de plataforma.
De mensajes a sincronización: la capa de arriba
Los WebSockets crudos mueven bytes; las aplicaciones quieren estado. El salto es la sincronización en tiempo real: en lugar de inventar a mano tipos de mensajes y contabilidad del lado del cliente, te suscribes a datos — una consulta, un documento, un canal — y la capa entrega eventos de cambio precisos, maneja la reconexión con puesta al día y aplica permisos del lado del servidor por suscriptor. Ese es el modelo de las live queries: WebSockets como transporte, un motor de consultas como cerebro. Si tu código de WebSocket está acumulando switch sobre tipos de mensajes, estás reconstruyendo esta capa a mano.
Casos de uso comunes
- Chat y mensajería — el caso canónico: ambos lados hablan, al instante.
- Presencia — quién está en línea, quién está escribiendo: mensajes diminutos, alta frecuencia, en ambos sentidos.
- Edición colaborativa — documentos y pizarras compartidas, donde posiciones de cursor y ediciones fluyen continuamente.
- Dashboards en vivo y tickers — push del servidor con números que cambian; SSE también encaja cuando es de un solo sentido.
- Multijugador y ubicación — estado de juego y marcadores de mapa en movimiento, donde la latencia es el producto.
¿Necesitas un socket? Matriz de decisión
| Elige WebSockets cuando… | HTTP plano es lo correcto cuando… |
|---|---|
| Los usuarios miran datos que cambian ahora | Los datos cambian rara vez o bajo demanda |
| Ambos lados inician mensajes | Solo el cliente pregunta |
| La latencia es visible para el usuario (chat, juegos) | Un poll de 30 segundos honestamente bastaría |
| Muchos mensajes pequeños fluyen constantemente | Las respuestas son grandes y cacheables |
| Vas a operar (o alquilar) el fan-out | Nadie es dueño de la operación de sockets |
Y el camino intermedio que la matriz esconde: los casos de solo servidor a cliente (feeds, notificaciones) encajan en SSE con menos maquinaria — la comparación completa de transportes tiene su propia entrada en el registro de este glosario.
Limitaciones y trade-offs
- El estado es el precio del push. Cada conexión abierta es memoria del servidor y una restricción de balanceo de carga; la ausencia de estado de HTTP cargaba más peso del que parecía.
- Las redes odian las conexiones de larga vida. Proxies, radios móviles y laptops cerrándose cortan sockets constantemente — la lógica de reconexión no es un caso borde, es el bucle principal.
- La seguridad se muda a la conexión. Autentica al conectar, valida cada mensaje, aplica autorización por suscripción — y siempre wss.
- El caching aquí no existe. Todo lo enviado por push se calcula y entrega por cliente; el CDN no puede ayudarte.
- La sincronización hecha a mano es una trampa. La distancia entre “abrí un socket” y “sincronización de estado correcta, con reconexión y permisos” es donde vive la ingeniería real — que es exactamente la capa que vale la pena alquilar.
WebSockets en Back4app
Back4app es una plataforma open-source de Backend as a Service (BaaS) que combina base de datos gestionada, APIs REST y GraphQL generadas automáticamente, autenticación, almacenamiento de archivos y funciones serverless con Cloud Code. Su capa de tiempo real es Live Query: el transporte WebSocket, los heartbeats, la reconexión y el fan-out multi-nodo corren como infraestructura gestionada (con el protocolo abierto LiveQuery por debajo), mientras tu código se suscribe a consultas y recibe eventos de cambio tipados — con ACLs aplicadas por suscriptor, para que el tiempo real nunca se salte el modelo de permisos. Las pestañas de código de arriba son toda la historia del lado del cliente.
Preguntas frecuentes
¿Qué es un WebSocket en términos simples?
Una llamada telefónica en lugar de un intercambio de cartas. HTTP es request-response — el cliente pregunta, el servidor responde, la línea se cierra. Un WebSocket abre una conexión persistente por la que ambos lados pueden enviar mensajes en cualquier momento, con unos pocos bytes de framing por mensaje en lugar de headers completos. Es el transporte estándar (RFC 6455) para chat, datos en vivo y colaboración.
¿En qué se diferencia un WebSocket de HTTP?
Dirección y tiempo de vida. HTTP es stateless e iniciado por el cliente: cada intercambio es una solicitud nueva con headers completos, y el servidor nunca puede hablar primero. Un WebSocket empieza como una solicitud HTTP, hace upgrade y se convierte en un canal full-duplex con estado donde el servidor hace push sin que se lo pidan — que es todo el punto para cualquier cosa que cambia mientras el usuario mira.
¿Cómo funciona el handshake de WebSocket?
Empieza como HTTP educado: el cliente envía un GET con los headers Upgrade y Connection más una Sec-WebSocket-Key aleatoria; el servidor responde 101 Switching Protocols con un hash de aceptación derivado de esa clave. Desde ese momento la conexión TCP deja de hablar HTTP y transporta frames ligeros de WebSocket en ambas direcciones hasta que alguno de los lados la cierra.
¿Cuál es la diferencia entre ws:// y wss://?
La misma que entre http y https: wss corre la conexión sobre TLS. El tráfico de producción siempre es wss — por privacidad y, en la práctica, porque las conexiones cifradas atraviesan proxies y middleboxes corporativos que estropean los upgrades en texto plano. No hay razón legítima para llevar ws a producción.
¿Cuál es la diferencia entre WebSockets y Server-Sent Events?
La dirección. SSE es de un solo sentido — el servidor transmite al cliente sobre HTTP plano, con reconexión automática incluida — ideal para feeds, tickers y notificaciones. Los WebSockets son bidireccionales, para todo donde el cliente también habla: chat, juegos, edición colaborativa. SSE es más simple donde alcanza; los WebSockets son la herramienta general.
¿Cómo funcionan las reconexiones y los heartbeats?
El protocolo incluye frames de control ping/pong para que cada lado verifique que el otro sigue vivo; las aplicaciones ponen heartbeats encima para detectar conexiones medio muertas, y luego se reconectan con backoff exponencial más jitter y vuelven a suscribir su estado. Las capas de tiempo real gestionadas manejan este ciclo por ti — el código de WebSocket hecho a mano que lo omite funciona justo hasta que las redes se comportan como redes.
¿Los WebSockets escalan?
Sí, con una mecánica distinta a la de HTTP: las conexiones tienen estado, así que los balanceadores de carga necesitan afinidad de sesión; transmitir a muchos clientes requiere un backplane de pub/sub para que cada nodo pueda hacer fan-out de los mensajes; y los consumidores lentos necesitan manejo de backpressure para que un cliente atascado no infle la memoria del servidor. Son problemas resueltos — en infraestructura que construyes o alquilas.
¿Cuándo NO deberías usar WebSockets?
Cuando request-response ya encaja: traer recursos cacheables, CRUD estándar, actualizaciones poco frecuentes. Una conexión persistente compra push instantáneo y lo paga en estado — sin sentido para datos que cambian rara vez. La regla práctica: si un polling cada 30 segundos honestamente alcanzaría, sáltate el socket.