You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Fiber v2.38.1结合fasthttp/websocket空指针panic排查问询

问题:Fiber+fasthttp/websocket部署Heroku触发空指针Panic

使用Fiber v2.38.1(底层依赖fasthttp/websocket v1.5.0)开发的应用部署在Heroku上时出现崩溃,错误日志显示空指针解引用panic,触发位置为github.com/fasthttp/websocket.(*Conn).beginMessage函数的conn.go:479行。

已确认连接实例c不为空,但panic仍会触发;且问题仅在CloseMsg的HttpCode为418时出现——该状态码对应Heroku因空闲终止连接的意外IO场景(伴随H15错误)。

目前已通过判断HttpCode为418时不发送关闭消息的方式临时解决问题,但希望明确该panic的根本原因。


相关代码

处理关闭消息的goroutine(content_ctl.go)

// 处理关闭消息 - 来自通道
// TODO: 是否使用goroutine池?
go func() {
    if r := recover(); r != nil { // TODO: 这样处理是否合适?
        fmt.Printf("从panic恢复: %v\n", r)
    }

    closeMsg := <-(*client).CloseChan // 处理关闭
    log.Infof("收到关闭消息: %v", closeMsg)

    // 发送关闭响应
    closeResp := &model.WsResp{
        Status: closeMsg.HttpCode,
        Source: model.RespSourceConn,
        Msg:    closeMsg.Msg,
    }

    log.Infof("连接是否为空: %v, 消息: %v\n", client.WsConn == nil, closeResp)
    err = client.WriteMsg(closeResp)
    if err != nil {
        log.Errorf("发送关闭消息出错: %v", closeResp)
    }

    ctl.cwm.CloseAndCleanup(client.Id) // 关闭并清理
}()

WsClient结构体及WriteMsg方法(ws_model.go)

// WebSocket客户端
type WsClient struct {
    WsUser
    ContentUuid string          `json:"contentUuid"` // 内容UUID
    WsConn      *websocket.Conn `json:"-"`           // WebSocket连接
    CloseChan   chan *CloseMsg  `json:"-"`           // 关闭通道
    WriteLock   *sync.Mutex     // 写入锁,避免并发写入WebSocket连接导致panic,写入或关闭时获取锁
}

// 写入WebSocket消息,带锁
func (wsc *WsClient) WriteMsg(msg *WsResp) error {
    if wsc.WsConn == nil {
        return errutil.ErrNoConn
    }
    wsc.WriteLock.Lock()
    err := wsc.WsConn.WriteJSON(msg)
    wsc.WriteLock.Unlock()
    return err
}

CloseMsg结构体(ws_model.go)

// 发送到关闭通道的关闭消息
type CloseMsg struct {
    HttpCode int    `json:"httpCode"`
    Msg      string `json:"msg"`
}

补充Heroku日志

2022-10-16T05:19:03.088622+00:00 heroku[router]: at=error code=H15 desc="Idle connection" method=GET path="/api/v1/content/ws/RgPx8znal7AJb
2022-10-16T05:19:03.065493+00:00 app[web.1]: time="2022-10-16T05:19:03Z" level=info msg="error - on read:  websocket: close 1006 (abnormal closure): unexpected EOF"
2022-10-16T05:20:57.758379+00:00 app[web.1]: time="2022-10-16T05:20:57Z" level=info msg="cleanup client, id = 'wscid-ee670cc5-4100-49d6-9857-8284d93a6d33'"
2022-10-16T05:20:57.758505+00:00 app[web.1]: time="2022-10-16T05:20:57Z" level=info msg="close msg received: &{418 close}"

日志显示Heroku会在连接空闲一段时间后终止连接,此时会触发418状态码的关闭消息。


内容的提问来源于stack exchange,提问作者Eric

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 21:45:37