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