¿Por qué Go y WebSockets son la combinación ideal para tiempo real?
Imagínese esta situación: lanza un chat en línea, un terminal bursátil o un juego multijugador. Los usuarios esperan una reacción instantánea. Nadie quiere actualizar la página manualmente o esperar 5 segundos hasta que llegue la respuesta del servidor. Aquí es donde entran en escena los WebSockets.
Go (Golang) es perfecto para esta tarea. Sus livianas gorutinas (goroutines) permiten mantener decenas de miles de conexiones simultáneas sin pérdida de rendimiento. Y la biblioteca estándar net/http junto con el paquete gorilla/websocket convierten la escritura de aplicaciones en tiempo real en un verdadero placer.
En este artículo, analizaremos cómo funciona WebSocket en Go, escribiremos un chat simple y discutiremos las mejores prácticas. ¡Allá vamos!
¿Qué es WebSocket y en qué es mejor que HTTP?
En resumen, WebSocket es un protocolo que establece una conexión bidireccional permanente entre el cliente (navegador) y el servidor. A diferencia del HTTP clásico, donde el cliente siempre inicia la solicitud, WebSocket permite que el servidor envíe datos al cliente en cualquier momento.
Las ventajas son obvias:
- Entrega instantánea — sin demoras para establecer una nueva conexión.
- Menos tráfico — los encabezados se envían solo una vez durante el handshake.
- Eficiencia — una sola conexión en lugar de miles de solicitudes HTTP.
Go maneja estas conexiones de manera excelente. En lugar de crear hilos del SO (lo cual es costoso), Go usa gorutinas. Una gorutina — una conexión. Miles de gorutinas trabajan en unos pocos hilos del SO, consumiendo un mínimo de memoria.
Instalación y preparación del proyecto en Go
Supongamos que ya tiene Go instalado. Si no — brew install go o descárguelo de golang.org.
Creemos un nuevo módulo:
mkdir go-websocket-chatcd go-websocket-chatgo mod init go-websocket-chatAhora instalemos la biblioteca más popular gorilla/websocket:
go get github.com/gorilla/websocketListo. Ahora tenemos todo para crear una aplicación en tiempo real en Go.
Escribiendo un servidor WebSocket en Go
Empecemos con lo más simple: un servidor eco. El cliente envía un mensaje, el servidor lo devuelve. Esto ayudará a entender la mecánica básica.
Paso 1: Estructura y actualización de la conexión
La conexión WebSocket comienza con una solicitud HTTP (handshake). El servidor debe "actualizarla" a WebSocket. En Go, esto se hace a través de http.Hijacker o mediante el conveniente método Upgrader del paquete gorilla/websocket.
Cree el archivo main.go:
package main
import ( "fmt" "log" "net/http" "github.com/gorilla/websocket")
var upgrader = websocket.Upgrader{ CheckOrigin: func(r *http.Request) bool { return true // permitimos cualquier origen (para desarrollo) },}
func handleWebSocket(w http.ResponseWriter, r *http.Request) { conn, err := upgrader.Upgrade(w, r, nil) if err != nil { log.Print("Error de actualización:", err) return } defer conn.Close()
// Bucle infinito de lectura y escritura for { messageType, message, err := conn.ReadMessage() if err != nil { log.Println("Error de lectura:", err) break } log.Printf("Recibido: %s", message)
// Enviamos lo mismo de vuelta err = conn.WriteMessage(messageType, message) if err != nil { log.Println("Error de escritura:", err) break } }}
func main() { http.HandleFunc("/ws", handleWebSocket) fmt.Println("Servidor iniciado en :8080") log.Fatal(http.ListenAndServe(":8080", nil))}Ejecute: go run main.go