@meshell #17 你给的截图里,最后一次客户端 ACK 确认服务端 Pong 之后,服务端主动发送 FIN ,说明断开是服务端的行为。 这个断开没有 opClose ,说明不是你的程序、也不是 ws 库的行为。 因为你是本地测试,也不会涉及防火墙。 由于 Ping/Pong 的间隔是 2s ,有双向通信,说明不是 Idle 相关的超时。也就是说,并不是 KeepAlive 等机制触发的先断开底层,再断开上层。 整个协议层面,在 ws 之下,还有(大概率)标准库 net/http ,再下层就是系统的 tcp socket 了。 我记忆中标准库 DefaultTransport 有个 30s 超时,查了一下 https://go.dev/src/net/http/transport.go 确实有,但是应该与你的问题无关。 正好你说你用的不是 http.client ,可以贴一下最小可复现的完整代码。因为之前的代码看不到 conn 的来源,可能是有哪个地方设置了超时参数。
@kuanat ```golang func (wh *wsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { conn, _, _, err := ws.UpgradeHTTP(r, w) if err != nil { logger.Errorf("Websocket upgrade failed : %s", err) return } client := &Client{ conn: conn, // fd: nfd(conn), server: wh.srv, id: uuid.New(), } logger.Infof("Client [%s] connected to [%s] as [%s]", conn.RemoteAddr(), conn.LocalAddr(), client.id) wh.srv.Lock() wh.srv.clients[client.id] = client wh.srv.Unlock() if wh.srv.OnConnect != nil { wh.srv.OnConnect(client) } // ... 下面的代码就是上面发的。这里的代码就是调用 ws 库,升级成 websocket.. 拿到链接. } ```