fix: harden websocket heartbeat under load
This commit is contained in:
+28
-6
@@ -28,14 +28,35 @@ import (
|
||||
const (
|
||||
// Time allowed to write a message to the peer.
|
||||
writeWait = 10 * time.Second
|
||||
|
||||
// Time allowed to read the next pong message from the peer.
|
||||
pongWait = idleSessionTimeout
|
||||
|
||||
// Send pings to peer with this period. Must be less than pongWait.
|
||||
pingPeriod = 15 * time.Second
|
||||
// Heartbeat defaults tolerate transient mobile and public-network stalls while
|
||||
// still detecting dead connections in a bounded amount of time.
|
||||
defaultWSPongWait = 90 * time.Second
|
||||
defaultWSPingPeriod = 15 * time.Second
|
||||
)
|
||||
|
||||
var (
|
||||
pongWait = defaultWSPongWait
|
||||
pingPeriod = defaultWSPingPeriod
|
||||
)
|
||||
|
||||
func configureWSHeartbeat(pingSeconds, pongSeconds int) error {
|
||||
ping := defaultWSPingPeriod
|
||||
pong := defaultWSPongWait
|
||||
if pingSeconds > 0 {
|
||||
ping = time.Duration(pingSeconds) * time.Second
|
||||
}
|
||||
if pongSeconds > 0 {
|
||||
pong = time.Duration(pongSeconds) * time.Second
|
||||
}
|
||||
if ping >= pong {
|
||||
return errors.New("websocket ping period must be shorter than pong wait")
|
||||
}
|
||||
pingPeriod = ping
|
||||
pongWait = pong
|
||||
immetrics.SetWSHeartbeatConfig(ping, pong)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sess *Session) closeWS() {
|
||||
if sess.proto == WEBSOCK {
|
||||
sess.ws.Close()
|
||||
@@ -52,6 +73,7 @@ func (sess *Session) readLoop() {
|
||||
sess.ws.SetReadDeadline(time.Now().Add(pongWait))
|
||||
sess.ws.SetPongHandler(func(string) error {
|
||||
atomic.StoreInt64(&sess.lastAction, types.TimeNow().UnixNano())
|
||||
immetrics.IncWSHeartbeat("pong_received")
|
||||
sess.refreshPresence("ws.pong")
|
||||
sess.ws.SetReadDeadline(time.Now().Add(pongWait))
|
||||
return nil
|
||||
|
||||
Reference in New Issue
Block a user