Exemple de WebSocket Fiber

Basé sur le composant WebSocket de Fasthttp de Fiber, la méthode *fiber.Ctx est utilisée, comme Locals, Params, Query, et Cookies. Voici un exemple d'utilisation de WebSocket dans Fiber.

Remarque : La version Go 1.18 et supérieure est requise.

Installation

go get -u github.com/gofiber/fiber/v2
go get -u github.com/gofiber/contrib/websocket

Signature de la Fonction

func New(handler func(*websocket.Conn), config ...websocket.Config) fiber.Handler {

Configuration

Propriété Type Description Valeur par défaut
Filter func(*fiber.Ctx) bool Définit une fonction pour ignorer le middleware. nil
HandshakeTimeout time.Duration HandshakeTimeout spécifie la durée pour terminer l'handshake. 0 (pas de limite de temps)
Subprotocols []string Subprotocols spécifie les sous-protocoles demandés par le client. nil
Origins []string Origines autorisées en fonction de l'en-tête Origin. Si vide, cela autorise toutes les origines. nil
ReadBufferSize int ReadBufferSize spécifie la taille du tampon d'E/S pour recevoir les messages (en octets). 0 (taille par défaut)
WriteBufferSize int WriteBufferSize spécifie la taille du tampon d'E/S pour envoyer les messages (en octets). 0 (taille par défaut)
WriteBufferPool websocket.BufferPool WriteBufferPool est le pool de mémoires tampon utilisé pour les opérations d'écriture. nil
EnableCompression bool EnableCompression spécifie si le client doit négocier la compression pour chaque message (RFC 7692). false
RecoverHandler func(*websocket.Conn) void RecoverHandler est une fonction de traitement pour la récupération des pannes. defaultRecover

Exemple

package main

import (
	"log"
	"github.com/gofiber/fiber/v2"
	"github.com/gofiber/contrib/websocket"
)

func main() {
	app := fiber.New()

	app.Use("/ws", func(c *fiber.Ctx) error {
		// Renvoie true si le client demande une mise à niveau vers le protocole WebSocket
		if websocket.IsWebSocketUpgrade(c) {
			c.Locals("allowed", true)
			return c.Next()
		}
		return fiber.ErrUpgradeRequired
	})

	app.Get("/ws/:id", websocket.New(func(c *websocket.Conn) {
		// c.Locals est ajouté à *websocket.Conn
		log.Println(c.Locals("allowed"))  // true
		log.Println(c.Params("id"))       // 123
		log.Println(c.Query("v"))         // 1.0
		log.Println(c.Cookies("session")) // ""

		var (
			mt  int
			msg []byte
			err error
		)
		for {
			if mt, msg, err = c.ReadMessage(); err != nil {
				log.Println("read:", err)
				break
			}
			log.Printf("reçu: %s", msg)

			if err = c.WriteMessage(mt, msg); err != nil {
				log.Println("write:", err)
				break
			}
		}
	}))

	log.Fatal(app.Listen(":3000"))
	// Accéder au serveur WebSocket : ws://localhost:3000/ws/123?v=1.0
	// https://www.websocket.org/echo.html
}

Remarques sur l'utilisation du Middleware de Cache

Si vous rencontrez une erreur "websocket: bad handshake" lors de l'utilisation du cache middleware, utilisez config.Next pour ignorer le chemin WebSocket.

app := fiber.New()
app.Use(cache.New(cache.Config{
	Next: func(c *fiber.Ctx) bool {
		return strings.Contains(c.Route().Path, "/ws")
	},
}))

app.Get("/ws/:id", websocket.New(func(c *websocket.Conn) {}))

Considérations concernant l'utilisation du middleware de récupération

En raison de raisons d'implémentation internes, le middleware de récupération est actuellement incompatible avec le middleware WebSocket. Veuillez utiliser config.RecoverHandler pour ajouter un gestionnaire de récupération pour les points de terminaison WebSocket. Par défaut, la configuration de RecoverHandler récupère les paniques, écrit la trace de la pile sur stderr, et renvoie également une réponse contenant le message de la panique dans le champ error.

app := fiber.New()

app.Use(cache.New(cache.Config{
    Next: func(c *fiber.Ctx) bool {
        return strings.Contains(c.Route().Path, "/ws")
    },
}))

cfg := Config{
    RecoverHandler: func(conn *Conn) {
        if err := recover(); err != nil {
            conn.WriteJSON(fiber.Map{"customError": "une erreur s'est produite"})
        }
    },
}

app.Get("/ws/:id", websocket.New(func(c *websocket.Conn) {}, cfg))