Esempio di WebSocket di Fiber

Basato sul componente WebSocket di Fasthttp di Fiber, viene utilizzato il metodo *fiber.Ctx, come ad esempio Locals, Params, Query e Cookies. Di seguito un esempio di utilizzo di WebSocket in Fiber.

Nota: È richiesta la versione 1.18 o successiva di Go.

Installazione

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

Firma della Funzione

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

Configurazione

Proprietà Tipo Descrizione Valore Predefinito
Filtro func(*fiber.Ctx) bool Definisce una funzione per saltare il middleware. nil
Timeout di Handshake time.Duration HandshakeTimeout specifica la durata per completare l'handshake. 0 (nessun timeout)
Sottoprotocolli []string Subprotocols specifica i sottoprotocolli richiesti dal client. nil
Origini []string Origini consentite in base all'intestazione di Origine. Se vuoto, consente qualsiasi origine. nil
Dimensione Buffer di Lettura int ReadBufferSize specifica la dimensione del buffer I/O per ricevere messaggi (in byte). 0 (dimensione predefinita)
Dimensione Buffer di Scrittura int WriteBufferSize specifica la dimensione del buffer I/O per inviare messaggi (in byte). 0 (dimensione predefinita)
Pool Buffer di Scrittura websocket.BufferPool WriteBufferPool è il pool buffer utilizzato per le operazioni di scrittura. nil
Abilita Compressione bool EnableCompression specifica se il client dovrebbe negoziare la compressione per ogni messaggio (RFC 7692). false
RecoverHandler func(*websocket.Conn) void RecoverHandler è una funzione di gestione per il recupero da un'eccezione. defaultRecover

Esempio

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 {
		// Restituisce true se il client richiede un upgrade al protocollo 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 viene aggiunto a *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("lettura:", err)
				break
			}
			log.Printf("ricezione: %s", msg)

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

	log.Fatal(app.Listen(":3000"))
	// Accesso al server WebSocket: ws://localhost:3000/ws/123?v=1.0
	// https://www.websocket.org/echo.html
}

Note sull'Utilizzo del Middleware Cache

Se incontri un errore websocket: bad handshake durante l'uso del middleware cache, utilizza config.Next per saltare il percorso 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) {}))

Considerazioni sull'utilizzo del middleware di ripristino

A causa di motivi di implementazione interna, attualmente il middleware di ripristino non è compatibile con il middleware WebSocket. Si prega di utilizzare config.RecoverHandler per aggiungere un gestore di ripristino per i punti finali WebSocket. Per impostazione predefinita, la configurazione di RecoverHandler recupera dai panici, scrive la traccia dello stack su stderr e restituisce anche una risposta contenente il messaggio di panico nel campo 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": "si è verificato un errore"})
        }
    },
}

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