
使用 Gorilla WebSocket 库可通过 WriteMessage 发送标准关闭帧(含状态码和可读消息),再调用 Close() 完成连接终止,使前端 JavaScript 的 onclose 事件能正确接收 event.code 和 event.reason。
使用 gorilla websocket 库可通过 `writemessage` 发送标准关闭帧(含状态码和可读消息),再调用 `close()` 完成连接终止,使前端 javascript 的 `onclose` 事件能正确接收 `event.code` 和 `event.reason`。
在 Go 中实现符合 WebSocket 协议规范的优雅关闭,关键在于主动发送 Close 消息帧(opcode 8),而非直接调用 Conn.Close()——后者仅底层断开 TCP 连接,不携带任何应用层关闭信息,导致浏览器无法解析 event.code 或 event.reason。
Gorilla WebSocket 提供了便捷工具函数 websocket.FormatCloseMessage(code int, text string),用于构造符合 RFC 6455 格式的关闭载荷(前 2 字节为 16 位无符号整数状态码,后续为 UTF-8 编码的可选原因文本)。示例代码如下:
import "github.com/gorilla/websocket"
// 假设 c 是已建立的 *websocket.Conn
cm := websocket.FormatCloseMessage(websocket.CloseGoingAway, "Server restarting gracefully")
if err := c.WriteMessage(websocket.CloseMessage, cm); err != nil {
log.Printf("Failed to send close message: %v", err)
// 注意:即使写入失败,仍建议尝试关闭连接
}
// 确保关闭底层连接
c.Close()
✅ 支持的常用状态码(来自 github.com/gorilla/websocket 包常量):
WebSocket 8.18.2 是该协议规范的一个重要迭代版本,主要优化了连接稳定性与数据传输效率。它通过全双工通信机制,允许客户端与服务器在单一长连接上实时交换数据,大幅降低传统 HTTP 轮询的开销。该版本增强了心跳保活、自动重连及二进制帧传输能力,适用于即时通讯、在线游戏及金融行情推送等低延迟场景,为开发者提供更可靠的实时网络交互基础。
- websocket.CloseNormalClosure(1000):正常关闭
- websocket.CloseGoingAway(1001):服务器即将下线
- websocket.CloseAbnormalClosure(1006):异常关闭(不可由应用层发送)
- websocket.ClosePolicyViolation(1008):违反策略
⚠️ 重要注意事项:
- golang.org/x/net/websocket(已归档废弃)不支持自定义关闭消息,其 Close() 方法无参数且不触发标准关闭握手。如需此功能,必须迁移到维护中的 Gorilla WebSocket 或 nhooyr.io/websocket。
- 关闭消息必须通过 WriteMessage(websocket.CloseMessage, payload) 发送,不可使用 WriteJSON 或 WriteMessage(websocket.TextMessage, ...) 替代。
- 浏览器端 event.code 和 event.reason 仅在服务端按协议发送了合法 Close 帧后才非空;若未发送或格式错误,二者将分别为 1006 和空字符串。
- 调用 WriteMessage 后应尽快调用 c.Close(),避免连接处于半关闭状态。
通过以上方式,你不仅能确保连接干净释放,还能向客户端传递明确的运维意图,大幅提升前后端协同调试与用户体验。










