c.IsWebSocket()仅检测Connection头含upgrade、Upgrade头为websocket,不验证密钥或版本;返回true仅表示合法握手请求,须立即调用c.Upgrade()获取*websocket.Conn并返回nil,否则连接被当作HTTP处理。

如何用 IsWebSocket() 检测并拦截 WebSocket 升级请求
Fiber 不自动升级 HTTP 连接为 WebSocket,必须手动检测握手头并显式处理。核心是调用 c.IsWebSocket() —— 它只做三件事:检查 Connection 头是否含 upgrade、Upgrade 头是否为 websocket、不验证密钥或版本(这些由底层 fasthttp 在升级时兜底)。它返回 true 仅表示“这是一个合法的 WebSocket 握手请求”,不代表连接已建立。
常见错误是直接在 IsWebSocket() == true 后写业务逻辑,却忘了调用 c.Upgrade() 或没及时返回,导致后续中间件继续执行、响应被写死为 HTTP 状态码。
- 必须在
IsWebSocket()为true后立即调用c.Upgrade(),否则连接会被当作普通 HTTP 处理 - 不能在
IsWebSocket()后调用c.Send()、c.JSON()等响应方法,会触发panic: connection has been upgraded -
路由路径需严格匹配,比如
app.Get("/ws", ...),不能写成app.Get("/ws/", ...)(尾部斜杠会导致Sec-WebSocket-Key头丢失)
c.Upgrade() 后怎么拿到原始 WebSocket 连接
c.Upgrade() 是 Fiber 的封装,它内部调用 fasthttp.Upgrade() 并返回一个 *websocket.Conn(来自 github.com/fasthttp/websocket)。你不能直接用标准库的 net/http WebSocket 类型,因为 Fiber 基于 fasthttp,二者不兼容。
典型写法是:
app.Get("/ws", func(c *fiber.Ctx) error {
if !c.IsWebSocket() {
return c.SendStatus(fiber.StatusUpgradeRequired)
}
conn, err := c.Upgrade()
if err != nil {
return err
}
// 此时 conn 是 *websocket.Conn,可直接 ReadMessage/WriteMessage
go handleConnection(conn)
return nil // 必须返回 nil,让 Fiber 不再写 HTTP 响应
})
注意:c.Upgrade() 只能调用一次,且必须在响应写出前;如果中间件链中有其他 handler 已写入 header,升级会失败并返回 ErrUpgradeRequired。
开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。
为什么路由注册必须用 app.Get() 而不是 app.Use() 或 app.All()
WebSocket 握手是 HTTP GET 请求,但语义上不是“获取资源”,而是“发起协议升级”。Fiber 的 app.Use() 是 middleware,会强制走完整中间件链,容易在某一层误写响应;app.All() 会匹配所有方法,但客户端发的握手一定是 GET,其他方法(如 POST)根本不会触发 IsWebSocket() 判断。
-
app.Get("/ws", ...)最安全:方法精准匹配,且天然排除 HEAD/OPTIONS 等干扰 - 不要在
app.Use()里做IsWebSocket()分支,因为c.Next()之后仍可能进入其他路由,导致重复升级或 panic - 如果需要鉴权,应在
IsWebSocket()之前校验 token 或 cookie,而不是依赖后续中间件
客户端连不上?重点检查这三处 header
Fiber 的 IsWebSocket() 很轻量,但它依赖的三个 header 缺一不可。浏览器原生 WebSocket 构造函数会自动带上全部,但用 curl 或 Postman 测试时极易漏掉:
-
Connection: upgrade(注意大小写和空格,不是Upgrade) -
Upgrade: websocket(值必须小写,大写WebSocket会失败) -
Sec-WebSocket-Key: xxx(base64 字符串,长度 24 字节,由客户端生成)
用 curl 测试时,命令必须写全:
curl -i \ -H "Connection: upgrade" \ -H "Upgrade: websocket" \ -H "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==" \ -H "Sec-WebSocket-Version: 13" \ http://localhost:3000/ws
少任何一个 header,IsWebSocket() 都返回 false,路由就进不到 Upgrade() 分支 —— 这是最常被忽略的调试盲点。










