fix(ws): 发送 WebSocket 协议级 Ping 控制帧防止 60s 后连接断开
writePump 只发 ActionCable 文本 JSON ping,从不发 websocket.PingMessage, 导致 readPump 的 PongHandler 永远不触发,ReadDeadline(60s) 到期后连接 被强制关闭。前端每 60 秒弹出"离线""重连"通知。 修复:在 ticker 中先发 PingMessage 控制帧(浏览器自动回 Pong 重置 ReadDeadline),再发 ActionCable 文本 ping(保活 ConnectionMonitor)。 同时包含此前会话中的其他变更: - 移除安全设置(SAML)页面及路由 - 新增超级管理员控制台前端页面 - platform agent_bots 路由使用 Platform* handler - 超级管理员入口改为 SPA 内路由跳转
This commit is contained in:
@@ -194,7 +194,19 @@ func (h *Handler) writePump(client *Client) {
|
||||
}
|
||||
|
||||
case <-ticker.C:
|
||||
// Send ActionCable-level ping message (JSON text frame).
|
||||
// Send WebSocket protocol-level ping control frame.
|
||||
// The browser automatically responds with a Pong, which triggers
|
||||
// the PongHandler in readPump and resets the ReadDeadline.
|
||||
// Without this, the ReadDeadline (PongWait=60s) expires and the
|
||||
// connection is forcibly closed, causing the client to show
|
||||
// "offline" / "reconnecting" notifications every ~60 seconds.
|
||||
client.Conn.SetWriteDeadline(time.Now().Add(WriteWait))
|
||||
if err := client.Conn.WriteMessage(websocket.PingMessage, nil); err != nil {
|
||||
logger.L().Errorf("ws: ws-ping control frame failed for user=%d: %v", client.UserID, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Also send ActionCable-level ping message (JSON text frame).
|
||||
// The JS ConnectionMonitor expects periodic ping messages to
|
||||
// keep the connection alive (staleThreshold = 6s by default).
|
||||
pingMsg, _ := json.Marshal(PingFrame{
|
||||
@@ -203,7 +215,7 @@ func (h *Handler) writePump(client *Client) {
|
||||
})
|
||||
client.Conn.SetWriteDeadline(time.Now().Add(WriteWait))
|
||||
if err := client.Conn.WriteMessage(websocket.TextMessage, pingMsg); err != nil {
|
||||
logger.L().Errorf("ws: ping write failed for user=%d: %v", client.UserID, err)
|
||||
logger.L().Errorf("ws: actioncable ping write failed for user=%d: %v", client.UserID, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user