一架梯子,一头程序猿,仰望星空!
Go Fiber教程 > 内容正文

Go Fiber Websocket例子


Fiber Websocket例子

基于Fiber的Fasthttp WebSocket组件,使用了 *fiber.Ctx 方法,如Locals、Params、Query和Cookies,下面介绍Fiber的websocket例子

注:需要 Go 1.18及以上版本

安装

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

函数签名

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

配置

属性 类型 描述 默认值
Filter func(*fiber.Ctx) bool 定义一个跳过中间件的函数。 nil
HandshakeTimeout time.Duration HandshakeTimeout 指定握手完成的持续时间。 0(无超时)
Subprotocols []string Subprotocols 指定客户端请求的子协议。 nil
Origins []string 基于 Origin 头部允许的 Origins。如果为空,表示允许任何 Origins。 nil
ReadBufferSize int ReadBufferSize 指定接收消息的 I/O 缓冲区大小(以字节为单位)。 0(使用默认大小)
WriteBufferSize int WriteBufferSize 指定发送消息的 I/O 缓冲区大小(以字节为单位)。 0(使用默认大小)
WriteBufferPool websocket.BufferPool WriteBufferPool 是用于写操作的缓冲区池。 nil
EnableCompression bool EnableCompression 指定客户端是否尝试协商每个消息的压缩(RFC 7692)。 false
RecoverHandler func(*websocket.Conn) void RecoverHandler 是一个恢复 panic 的处理函数。 defaultRecover

示例

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 {
        // 如果客户端请求升级到WebSocket协议,则返回true
        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是添加到*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"))
    // 访问WebSocket服务器:ws://localhost:3000/ws/123?v=1.0
    // https://www.websocket.org/echo.html
}

使用缓存中间件的注意事项

如果在使用缓存中间件时遇到websocket: bad handshake错误,请使用config.Next跳过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) {}))

使用恢复中间件的注意事项

出于内部实现原因,目前恢复中间件与WebSocket中间件不兼容,请使用config.RecoverHandler为WebSocket端点添加恢复处理程序。默认情况下,配置RecoverHandler从panic中恢复,并将堆栈跟踪写入stderr,还返回一个包含error字段中panic消息的响应。

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))