diff --git a/client.go b/client.go index 299ec0c7..3a5fc2de 100644 --- a/client.go +++ b/client.go @@ -1229,7 +1229,10 @@ func (c *Client) do(req *base.Request, skipResponse bool) (*base.Response, error c.session = sx.Session if sx.Timeout != nil && *sx.Timeout > 0 { - c.keepAlivePeriod = time.Duration(*sx.Timeout) * time.Second * 8 / 10 + c.keepAlivePeriod = max( + (time.Duration(*sx.Timeout)*time.Second)-5*time.Second, + 1*time.Second, + ) } } diff --git a/client_play_test.go b/client_play_test.go index 83e8d28e..382ca011 100644 --- a/client_play_test.go +++ b/client_play_test.go @@ -3908,7 +3908,7 @@ func TestClientPlayBackChannel(t *testing.T) { } return ptrOf(ProtocolUDP) }(), - senderReportPeriod: 500 * time.Millisecond, + senderReportPeriod: 750 * time.Millisecond, receiverReportPeriod: 750 * time.Millisecond, } diff --git a/server_session.go b/server_session.go index 9c1d5c93..777afd67 100644 --- a/server_session.go +++ b/server_session.go @@ -882,9 +882,14 @@ func (ss *ServerSession) runInner() error { res.Header = make(base.Header) } + // Media Foundation-based software, like Windows Media Player, + // send keepalives at an interval equal the timeout value. + // prevent timeouts by subtracting 5 seconds from the value. + timeout := max(int(ss.s.IdleTimeout/time.Second)-5, 1) + res.Header["Session"] = headers.Session{ Session: ss.secretID, - Timeout: ptrOf(uint(ss.s.IdleTimeout / time.Second)), + Timeout: ptrOf(uint(timeout)), }.Marshal() }