diff --git a/structs.go b/structs.go index a7b30dd4d..4465ec52c 100644 --- a/structs.go +++ b/structs.go @@ -85,6 +85,9 @@ type Session struct { // Stores the last HeartbeatAck that was recieved (in UTC) LastHeartbeatAck time.Time + // Stores the last Heartbeat sent (in UTC) + LastHeartbeatSent time.Time + // used to deal with rate limits Ratelimiter *RateLimiter diff --git a/wsapi.go b/wsapi.go index 1e2a866ad..8ecaaa772 100644 --- a/wsapi.go +++ b/wsapi.go @@ -267,6 +267,13 @@ type helloOp struct { // FailedHeartbeatAcks is the Number of heartbeat intervals to wait until forcing a connection restart. const FailedHeartbeatAcks time.Duration = 5 * time.Millisecond +// HeartbeatLatency returns the latency between heartbeat acknowledgement and heartbeat send. +func (s *Session) HeartbeatLatency() time.Duration { + + return s.LastHeartbeatAck.Sub(s.LastHeartbeatSent) + +} + // heartbeat sends regular heartbeats to Discord so it knows the client // is still connected. If you do not send these heartbeats Discord will // disconnect the websocket connection after a few seconds. @@ -289,6 +296,7 @@ func (s *Session) heartbeat(wsConn *websocket.Conn, listening <-chan interface{} sequence := atomic.LoadInt64(s.sequence) s.log(LogDebug, "sending gateway websocket heartbeat seq %d", sequence) s.wsMutex.Lock() + s.LastHeartbeatSent = time.Now().UTC() err = wsConn.WriteJSON(heartbeatOp{1, sequence}) s.wsMutex.Unlock() if err != nil || time.Now().UTC().Sub(last) > (heartbeatIntervalMsec*FailedHeartbeatAcks) {