Fiber WebSocket Example
Based on the Fiber's Fasthttp WebSocket component, the *fiber.Ctx
method is used, such as Locals, Params, Query, and Cookies. Here is an example of using WebSocket in Fiber.
Note: Go version 1.18 and above is required.
Installation
go get -u github.com/gofiber/fiber/v2
go get -u github.com/gofiber/contrib/websocket
Function Signature
func New(handler func(*websocket.Conn), config ...websocket.Config) fiber.Handler {
Configuration
Property | Type | Description | Default Value |
---|---|---|---|
Filter | func(*fiber.Ctx) bool |
Defines a function to skip the middleware. | nil |
HandshakeTimeout | time.Duration |
HandshakeTimeout specifies the duration for completing the handshake. | 0 (no timeout) |
Subprotocols | []string |
Subprotocols specify the client's requested subprotocols. | nil |
Origins | []string |
Origins allowed based on the Origin header. If empty, it allows any origins. | nil |
ReadBufferSize | int |
ReadBufferSize specifies the I/O buffer size for receiving messages (in bytes). | 0 (default size) |
WriteBufferSize | int |
WriteBufferSize specifies the I/O buffer size for sending messages (in bytes). | 0 (default size) |
WriteBufferPool | websocket.BufferPool |
WriteBufferPool is the buffer pool used for write operations. | nil |
EnableCompression | bool |
EnableCompression specifies whether the client should negotiate compression for each message (RFC 7692). | false |
RecoverHandler | func(*websocket.Conn) void |
RecoverHandler is a handling function for recovering from panic. | defaultRecover |
Example
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 {
// Returns true if the client requests an upgrade to the WebSocket protocol
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 is added to *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"))
// Access WebSocket server: ws://localhost:3000/ws/123?v=1.0
// https://www.websocket.org/echo.html
}
Notes on Using Cache Middleware
If you encounter a websocket: bad handshake
error while using cache middleware, use config.Next
to skip the WebSocket path.
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) {}))
Considerations for using the recovery middleware
Due to internal implementation reasons, the recovery middleware is currently incompatible with the WebSocket middleware. Please use config.RecoverHandler
to add a recovery handler for the WebSocket endpoints. By default, the RecoverHandler
configuration recovers from panics, writes the stack trace to stderr, and also returns a response containing the panic message in the error field.
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))