Ejemplo de WebSocket con Fiber
Basado en el componente de WebSocket de Fasthttp de Fiber, se utiliza el método *fiber.Ctx
, como Locals, Params, Query y Cookies. Aquí tienes un ejemplo de cómo usar WebSocket en Fiber.
Nota: Se requiere la versión 1.18 o superior de Go.
Instalación
go get -u github.com/gofiber/fiber/v2
go get -u github.com/gofiber/contrib/websocket
Firma de la Función
func New(handler func(*websocket.Conn), config ...websocket.Config) fiber.Handler {
Configuración
Propiedad | Tipo | Descripción | Valor Predeterminado |
---|---|---|---|
Filter | func(*fiber.Ctx) bool |
Define una función para omitir el middleware. | nil |
HandshakeTimeout | time.Duration |
HandshakeTimeout especifica la duración para completar el handshake. | 0 (sin tiempo de espera) |
Subprotocols | []string |
Subprotocols especifica los subprotocolos solicitados por el cliente. | nil |
Orígenes | []string |
Orígenes permitidos basados en el encabezado de Origen. Si está vacío, permite todos los orígenes. | nil |
ReadBufferSize | int |
ReadBufferSize especifica el tamaño del buffer de E/S para recibir mensajes (en bytes). | 0 (tamaño predeterminado) |
WriteBufferSize | int |
WriteBufferSize especifica el tamaño del buffer de E/S para enviar mensajes (en bytes). | 0 (tamaño predeterminado) |
WriteBufferPool | websocket.BufferPool |
WriteBufferPool es el pool de buffers usado para operaciones de escritura. | nil |
EnableCompression | bool |
EnableCompression especifica si el cliente debería negociar la compresión para cada mensaje (RFC 7692). | false |
RecoverHandler | func(*websocket.Conn) void |
RecoverHandler es una función de manejo para recuperarse de un pánico. | defaultRecover |
Ejemplo
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 {
// Devuelve true si el cliente solicita una actualización al protocolo 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 se agrega 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("read:", err)
break
}
log.Printf("recv: %s", msg)
if err = c.WriteMessage(mt, msg); err != nil {
log.Println("write:", err)
break
}
}
}))
log.Fatal(app.Listen(":3000"))
// Accede al servidor WebSocket: ws://localhost:3000/ws/123?v=1.0
// https://www.websocket.org/echo.html
}
Notas sobre el Uso del Middleware de Caché
Si encuentras un error websocket: bad handshake
al usar el middleware de caché, utiliza config.Next
para omitir la ruta de 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) {}))
Consideraciones para usar el middleware de recuperación
Debido a razones de implementación interna, el middleware de recuperación actualmente es incompatible con el middleware de WebSocket. Por favor, utilice config.RecoverHandler
para agregar un controlador de recuperación para los puntos finales de WebSocket. Por defecto, la configuración de RecoverHandler
se recupera de los panics, escribe la traza de la pila en stderr, y también devuelve una respuesta que contiene el mensaje de panic en el campo de 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": "error occurred"})
}
},
}
app.Get("/ws/:id", websocket.New(func(c *websocket.Conn) {}, cfg))