Exemplo de WebSocket do Fiber

Com base no componente WebSocket do Fasthttp do Fiber, o método *fiber.Ctx é usado, como Locais, Parâmetros, Consulta e Cookies. Aqui está um exemplo de uso do WebSocket no Fiber.

Observação: A versão 1.18 ou superior do Go é necessária.

Instalação

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

Assinatura da Função

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

Configuração

Propriedade Tipo Descrição Valor Padrão
Filtro func(*fiber.Ctx) bool Define uma função para pular o middleware. nil
HandshakeTimeout time.Duration HandshakeTimeout especifica a duração para completar o handshake. 0 (sem tempo limite)
Subprotocolos []string Subprotocolos especificam os subprotocolos solicitados pelo cliente. nil
Origens []string Origens permitidas com base no cabeçalho de Origem. Se estiver vazio, permite quaisquer origens. nil
TamanhoBufferLeitura int ReadBufferSize especifica o tamanho do buffer de E/S para receber mensagens (em bytes). 0 (tamanho padrão)
TamanhoBufferEscrita int WriteBufferSize especifica o tamanho do buffer de E/S para enviar mensagens (em bytes). 0 (tamanho padrão)
WriteBufferPool websocket.BufferPool WriteBufferPool é o pool de buffers usado para operações de escrita. nil
HabilitarCompressão bool EnableCompression especifica se o cliente deve negociar a compressão para cada mensagem (RFC 7692). false
RecoverHandler func(*websocket.Conn) void RecoverHandler é uma função de tratamento para recuperação de pânico. defaultRecover

Exemplo

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 {
		// Retorna true se o cliente solicitar uma atualização para o protocolo WebSocket
		if websocket.IsWebSocketUpgrade(c) {
			c.Locals("permitido", true)
			return c.Next()
		}
		return fiber.ErrUpgradeRequired
	})

	app.Get("/ws/:id", websocket.New(func(c *websocket.Conn) {
		// c.Locals é adicionado ao *websocket.Conn
		log.Println(c.Locals("permitido"))  // 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("leitura:", err)
				break
			}
			log.Printf("recebido: %s", msg)

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

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

Notas sobre o Uso do Middleware de Cache

Se encontrar um erro websocket: bad handshake ao usar o middleware de cache, use config.Next para pular o caminho do 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) {}))

Considerações para usar o middleware de recuperação

Devido a razões de implementação interna, o middleware de recuperação é atualmente incompatível com o middleware de WebSocket. Por favor, utilize config.RecoverHandler para adicionar um manipulador de recuperação para os pontos finais de WebSocket. Por padrão, a configuração do RecoverHandler recupera panes, escreve o rastreamento de pilha para stderr e também retorna uma resposta contendo a mensagem de pane no campo de erro.

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": "ocorreu um erro"})
        }
    },
}

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