Nouveau : Datasets open source gratuits disponibles !Decouvrir →
🐹
Avance 25 min Go

WebSockets avec Go

Pourquoi WebSockets avec Go ?

WebSockets est une technologie qui permet aux navigateurs et aux serveurs d'établir des connexions persistantes sur lesquelles ils peuvent échanger des données en temps réel. Dans un contexte professionnel, cela peut être utile pour de nombreux cas d'usage, comme le développement d'applications de chat en direct, la mise à jour en temps réel de l'état d'une application, ou encore la création d'applications multijoueurs.

Un cas concret serait une application de chat en direct. Avec un WebSocket, chaque utilisateur peut se connecter au serveur et recevoir des mises à jour en temps réel dès qu'un autre utilisateur envoie un message. Sans WebSocket, chaque message devrait être traité individuellement et le navigateur doit faire plusieurs requêtes pour obtenir les dernières informations.

Prerequis

  • Connaissances du langage Go
  • Connaissance de l'écosystème Go (Go modules, etc.)
  • Connaissance des concepts de base en programmation asynchrone
  • Une installation récente de Go (1.18 ou plus)
  • Un serveur web comme net/http
  • L'outil go run pour exécuter rapidement du code

Concepts fondamentaux

Connexion WebSocket

Un WebSocket est établi entre un client et un serveur à l'aide d'une requête HTTP. Le protocole de connexion est basé sur le protocole HTTP, mais une négociation supplémentaire est effectuée pour passer au protocole WebSocket.

package main

import (
    "fmt"
    "log"
    "net/http"

    "github.com/gorilla/websocket"
)

var upgrader = websocket.Upgrader{} // use default options

func echo(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 {
        messageType, message, err := conn.ReadMessage()
        if err != nil {
            log.Println("read:", err)
            break
        }
        log.Printf("recv: %s", message)
        err = conn.WriteMessage(messageType, message)
        if err != nil {
            log.Println("write:", err)
            break
        }
    }
}

func main() {
    http.HandleFunc("/echo", echo)
    log.Fatal(http.ListenAndServe(":8080", nil))
}

Envoi et réception de messages

Une fois la connexion établie, le client peut envoyer des messages au serveur et recevoir des réponses. Dans l'exemple ci-dessus, chaque message reçu est envoyé de nouveau au client.

Gestion des erreurs

La gestion des erreurs est essentielle pour assurer une bonne communication. Voici un exemple de gestion d'erreur lors de la lecture d'un message :

messageType, message, err := conn.ReadMessage()
if err != nil {
    log.Println("read:", err)
    break
}

Différences entre HTTP et WebSocket

  • HTTP est un protocole request-response. Une requête HTTP peut être envoyée et une réponse reçue, mais la connexion est fermée après l'échange.
  • WebSocket est un protocole bidirectionnel qui permet de garder la connexion ouverte pour échanger des données en temps réel.

Mise en pratique : projet fil rouge

Nous allons créer un simple application de chat en direct utilisant WebSockets. L'application sera basée sur le framework Go et nous utiliserons gorilla/websocket pour gérer les connexions WebSocket.

Étape 1 : Créer une nouvelle application Go

Créez un nouveau fichier main.go :

package main

import (
    "fmt"
    "log"
    "net/http"

    "github.com/gorilla/websocket"
)

var upgrader = websocket.Upgrader{} // use default options

func echo(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 {
        messageType, message, err := conn.ReadMessage()
        if err != nil {
            log.Println("read:", err)
            break
        }
        log.Printf("recv: %s", message)
        err = conn.WriteMessage(messageType, message)
        if err != nil {
            log.Println("write:", err)
            break
        }
    }
}

func main() {
    http.HandleFunc("/echo", echo)
    log.Fatal(http.ListenAndServe(":8080", nil))
}

Étape 2 : Créer un template HTML pour le chat

Créez un nouveau fichier index.html :

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Chat WebSocket</title>
</head>
<body>
    <h1>Chat WebSocket</h1>
    <div id="messages"></div>
    <input type="text" id="messageInput" placeholder="Type a message...">
    <button onclick="sendMessage()">Send</button>

    <script>
        const socket = new WebSocket("ws://localhost:8080/echo");

        socket.onopen = function() {
            console.log("WebSocket connection established");
        };

        socket.onmessage = function(event) {
            const messagesDiv = document.getElementById('messages');
            const message = document.createElement('div');
            message.textContent = event.data;
            messagesDiv.appendChild(message);
        };

        function sendMessage() {
            const input = document.getElementById('messageInput');
            const message = input.value;
            socket.send(message);
            input.value = '';
        }
    </script>
</body>
</html>

Étape 3 : Ajouter le template HTML à votre application Go

Modifiez main.go pour servir le fichier index.html :

package main

import (
    "fmt"
    "log"
    "net/http"

    "github.com/gorilla/websocket"
)

var upgrader = websocket.Upgrader{} // use default options

func echo(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 {
        messageType, message, err := conn.ReadMessage()
        if err != nil {
            log.Println("read:", err)
            break
        }
        log.Printf("recv: %s", message)
        err = conn.WriteMessage(messageType, message)
        if err != nil {
            log.Println("write:", err)
            break
        }
    }
}

func serveHTML(w http.ResponseWriter, r *http.Request) {
    http.ServeFile(w, r, "index.html")
}

func main() {
    http.HandleFunc("/echo", echo)
    http.HandleFunc("/", serveHTML)
    log.Fatal(http.ListenAndServe(":8080", nil))
}

Étape 4 : Exécuter l'application

Assurez-vous que vous avez le répertoire du projet dans votre GOPATH ou utilisez Go modules :

go mod init chatapp
go get github.com/gorilla/websocket
go run main.go

Ouvrez un navigateur et accédez à http://localhost:8080. Vous devriez voir une interface de chat simple où vous pouvez envoyer et recevoir des messages.

Erreurs frequentes et debugging

Erreur 1 : Connection refused

## ❌ Mauvais
go run main.go

Message d'erreur :

listen tcp :8080: listen: address already in use

Code corrige :

## 🔄 Corriger l'adresse IP ou le port
netstat -tuln | grep 8080
kill <PID>
go run main.go

Erreur 2 : Invalid argument

## ❌ Mauvais
upgrader := websocket.Upgrader{}

Message d'erreur :

panic: invalid argument to net.ListenUnixgram

Code corrige :

## 🔄 Utiliser une adresse IP valide
upgrader := websocket.Upgrader{ReadBufferSize: 1024, WriteBufferSize: 1024}

Erreur 3 : Unexpected EOF

## ❌ Mauvais
messageType, message, err := conn.ReadMessage()
if err != nil {
    log.Println("read:", err)
    break
}

Message d'erreur :

read: unexpected EOF

Code corrige :

## 🔄 Vérifier que le client n'a pas fermé la connexion
messageType, message, err := conn.ReadMessage()
if err != nil {
    if websocket.IsCloseError(err, websocket.CloseNormalClosure) {
        log.Println("Client closed connection")
    } else {
        log.Println("read:", err)
    }
    break
}

Pour aller plus loin

Piste 1 : Authentification et sécurité

Ajoutez une couche d'authentification et de sécurité à votre application WebSocket. Utilisez des jetons JWT pour authentifier les utilisateurs.

Piste 2 : Espace privé

Créez un espace privé où chaque utilisateur peut envoyer des messages à d'autres utilisateurs spécifiques.

Piste 3 : Gestion des groupes

Ajoutez la possibilité de créer et rejoindre des groupes. Les membres du même groupe peuvent échanger des messages entre eux.

Défi pratique

Créez une application de chat en direct avec plusieurs fonctionnalités supplémentaires, comme :

  • Authentification via JWT
  • Salles privées
  • Notifications push pour les nouveaux messages
  • Histoire des conversations

Besoin d'aide sur Go ?

Besoin d'aide sur un projet technique ? Decrivez-le pour des conseils personnalises.

Recevoir des conseils

Questions frequentes

Qu'est-ce que WebSockets et pourquoi l'utiliser avec Go ?
WebSockets est une technologie qui permet d'établir une connexion persistante entre un client et un serveur, facilitant la communication bidirectionnelle. Avec Go, on peut créer des serveurs WebSocket performants et faciles à gérer.
Comment installer le package Go pour les WebSockets ?
Pour installer le package Go pour les WebSockets, exécutez la commande `go get github.com/gorilla/websocket`. Cela télécharge et installe le package Gorilla WebSocket, qui est populaire pour gérer les communications WebSocket en Go.
Quels sont les avantages de utiliser des WebSockets avec Go dans un projet web moderne ?
L'utilisation de WebSockets avec Go permet une communication réactive et temps-réel entre le client et le serveur. Cela améliore l'expérience utilisateur en offrant une interactivité plus fluide, notamment pour les applications chat, jeux en ligne ou dashboards dynamiques.

Pages liees

Chaque semaine, le meilleur de la tech francaise

Tendances, salaires, outils et opportunites — directement dans votre boite mail.

Gratuit. Desabonnement en un clic. Pas de spam.