Introduction à WebSocket en Go : pourquoi le temps réel ?
Les applications web modernes exigent de plus en plus une livraison instantanée des données. Le traditionnel modèle requête/réponse HTTP ne suffit plus pour les chats, les jeux en ligne, les cotations boursières et les tableaux de bord de monitoring. C'est là qu'intervient WebSocket — un protocole assurant une connexion bidirectionnelle permanente entre le client et le serveur. Dans cet article, nous allons voir comment créer des applications temps réel en Go (Golang) avec WebSocket, de l'installation aux solutions de production.
Go est idéal pour WebSocket grâce à son modèle de concurrence léger (goroutines) et ses hautes performances. Nous passerons d'un simple serveur écho à un chat complet et un système de monitoring.
Fondamentaux de WebSocket et configuration de l'environnement
Qu'est-ce que WebSocket ?
WebSocket est un protocole fonctionnant au-dessus de TCP. Il commence par une poignée de main HTTP (upgrade), après quoi la connexion bascule vers un canal bidirectionnel permanent. Contrairement à HTTP, le serveur peut envoyer des données au client sans requête — c'est la base du temps réel.
Installation et bibliothèques
Go ne dispose pas de bibliothèque standard pour WebSocket, mais il existe la bibliothèque populaire gorilla/websocket. Installons-la :
go get github.com/gorilla/websocketOn peut aussi utiliser nhooyr.io/websocket (une alternative plus moderne), mais dans cet article nous nous concentrerons sur gorilla comme la plus répandue.
Premier serveur WebSocket en Go
Écrivons un simple serveur écho qui reçoit un message et le renvoie :
package main
import ( "log" "net/http" "github.com/gorilla/websocket")
var upgrader = websocket.Upgrader{ CheckOrigin: func(r *http.Request) bool { return true // pour le développement },}
func echoHandler(w http.ResponseWriter, r *http.Request) { conn, err := upgrader.Upgrade(w, r, nil) if err != nil { log.Print("Upgrade:", err) return } defer conn.Close()
for { mt, message, err := conn.ReadMessage() if err != nil { log.Println("Read:", err) break } log.Printf("Received: %s", message) err = conn.WriteMessage(mt, message) if err != nil { log.Println("Write:", err) break } }}
func main() { http.HandleFunc("/echo", echoHandler) log.Println("Server started on :8080") log.Fatal(http.ListenAndServe(":8080", nil))}Ceci est un exemple fonctionnel minimal. Notez l'Upgrader — il vérifie les en-têtes HTTP et bascule la connexion.
Architecture d'une application temps réel : chat en Go
Gestion des connexions
Pour un chat, il faut gérer plusieurs clients. Créons une structure Hub qui stockera toutes les connexions actives et diffusera les messages :
type Client struct { hub *Hub conn *websocket.Conn send chan []byte}
type Hub struct { clients map[*Client]bool broadcast chan []byte register chan *Client unregister chan *Client}
func newHub() *Hub { return &Hub{ clients: make(map[*Client]bool), broadcast: make(chan []byte), register: make(chan *Client), unregister: make(chan *Client), }}
func (h *Hub) run() { for { select { case client := <-h.register: h.clients[client] = true case client := <-h.unregister: if _, ok := h.clients[client]; ok { delete(h.clients, client) close(client.send) } case message := <-h.broadcast: for client := range h.clients { select { case client.send <- message: default: