wsc
WebSocket 服务端框架 + 配套客户端,同一 Message 信封、同一处协议定义。
信封格式:{"action":"...","payload":...}(Message 结构体,payload 为 json.RawMessage)。
心跳约定:双方默认 60s 读超时 + 周期 ping(客户端 PongTimeout 需 ≥ 服务端 ping 周期 54s,默认值即满足)。
服务端
import "git.zeroonesoft.cn/golib/zogo/wsc"
wsc.HandleWS(r, "/ws/chat", wsc.QuickServer(onConnect, onDisconnect), func(router *wsc.Router) {
// 带响应:fn 返回 (resp, error),resp 序列化后以同名 action+".resp" 语义回包
router.On("ping", wsc.Bind(func(ctx *wsc.Context, req *PingReq) (*PingResp, error) {
return &PingResp{Pong: true}, nil
}))
// 无响应 / 客户端约定固定回包类型时
router.On("register", wsc.BindNoResp(func(ctx *wsc.Context, req *RegisterReq) error { ... }))
})
Server:连接池与房间管理(GetOrCreateRoom/ActiveCount…),OnConnect/OnDisconnect/OnUpgrade钩子Router:action 分发,反射校验 handler 签名;Use挂中间件Context:单会话上下文,实现context.Context;WriteMessage/WriteError/JoinRoom/Set…,WriteError使用WsActionErroraction- gin 耦合仅在
HandleWS/newContext/OnUpgrade三处入口,核心零 gin
客户端
cli := wsc.NewClient(wsc.DefaultClientConfig("wss://cloud/ws/gateway?token=xxx"))
cli.On("kick", wsc.BindPayload(func(req *KickReq) { ... }))
cli.OnConnected = func() { cli.Send("register", &RegisterReq{...}) }
cli.SetURL("wss://cloud/ws/gateway?token=新token") // 重连时生效
_ = cli.Connect() // AutoReconnect=true 时阻塞到连上(指数退避,稳定 10s 后重置)
defer cli.Close()
- 自动重连:指数退避(1s→30s 封顶),连接稳定满 10s 才重置退避,防抖动时"永远 1s 一连"
- 断线期间
Send返回错误;重连成功重建读写泵,OnConnected重新触发(在此做重注册/重订阅)
线程安全
Client 与 Session 的公开方法均可并发调用;发送走带缓冲通道 + 单写泵。