Biblioteca WebSocket Go (Golang): gorilla/websocket y el estándar net/http
WebSocket es un protocolo que proporciona comunicación full-duplex entre el cliente y el servidor a través de una única conexión TCP de larga duración. A diferencia del HTTP clásico, una vez establecida la conexión, los datos pueden transmitirse en ambas direcciones en cualquier momento, sin solicitudes constantes del cliente. Es la solución ideal para chats, notificaciones en tiempo real, juegos en línea y plataformas de trading.
En el ecosistema de Go (Golang), existen varias formas de trabajar con WebSocket. La más popular y probada en el tiempo es la biblioteca gorilla/websocket. Sin embargo, a partir de Go 1.22, es posible implementar un servidor WebSocket básico sin dependencias externas, utilizando el paquete estándar net/http. En este artículo, analizaremos ambos enfoques en detalle.
Instalación de la biblioteca gorilla/websocket
Para comenzar a trabajar con gorilla/websocket, instálela mediante go get:
go get github.com/gorilla/websocketLa biblioteca proporciona una API conveniente para crear tanto la parte del servidor como la del cliente. Maneja el handshake, el enmarcado de mensajes, admite compresión y ping/pong automáticos.
Servidor WebSocket con gorilla/websocket
Veamos un ejemplo de un servidor echo simple. El cliente envía un mensaje y el servidor lo devuelve:
package main
import ( "log" "net/http" "github.com/gorilla/websocket")
var upgrader = websocket.Upgrader{ CheckOrigin: func(r *http.Request) bool { return true // permitir cualquier origen (para desarrollo) },}
func echoHandler(w http.ResponseWriter, r *http.Request) { conn, err := upgrader.Upgrade(w, r, nil) if err != nil { log.Print("Upgrade fallido:", err) return } defer conn.Close()
for { messageType, message, err := conn.ReadMessage() if err != nil { log.Println("Error de lectura:", err) break } log.Printf("Recibido: %s", message)
if err := conn.WriteMessage(messageType, message); err != nil { log.Println("Error de escritura:", err) break } }}
func main() { http.HandleFunc("/echo", echoHandler) log.Fatal(http.ListenAndServe(":8080", nil))}Aquí, Upgrader convierte una solicitud HTTP normal en una conexión WebSocket. La función CheckOrigin controla desde qué dominios se permiten las conexiones. En producción, se recomienda verificar orígenes específicos.
Cliente WebSocket con gorilla/websocket
Ejemplo de un cliente que se conecta a nuestro servidor y envía un mensaje:
package main
import ( "log" "os" "os/signal" "time" "github.com/gorilla/websocket")
func main() { interrupt := make(chan os.Signal, 1) signal.Notify(interrupt, os.Interrupt)
url := "ws://localhost:8080/echo" c, _, err := websocket.DefaultDialer.Dial(url, nil) if err != nil { log.Fatal("dial:", err) } defer c.Close()
done := make(chan struct{})
// Goroutine para leer respuestas go func() { defer close(done) for { _, message, err := c.ReadMessage() if err != nil { log.Println("read:", err) return } log.Printf("recv: %s", message) } }()
// Envío de mensaje ticker := time.NewTicker(time.Second) defer ticker.Stop()
for { select { case <-done: return case t := <-ticker.C: err := c.WriteMessage(websocket.TextMessage, []byte(t.String())) if err != nil { log.Println("write:", err) return } case <-interrupt: log También en la biblioteca
Wire para Go: guía completa con ejemplos
StackExchange.Redis para C# (.NET): guía completa con ejemplos
Envío de correo electrónico en Swift (iOS/macOS): MFMailComposeViewController y SMTP
Generación de PDF en Go: Revisión de bibliotecas y guía práctica
Autorización y autenticación en Java: Spring Security y JWT