From 356e05e3af7702b7dfefbba6e936d602c3638055 Mon Sep 17 00:00:00 2001 From: Bond-009 Date: Wed, 17 Apr 2024 18:44:39 +0200 Subject: Changes SessionWebSocketListener to (re)use a timer (#11358) --- .../Session/SessionWebSocketListener.cs | 114 ++++++--------------- 1 file changed, 31 insertions(+), 83 deletions(-) (limited to 'Emby.Server.Implementations/Session') diff --git a/Emby.Server.Implementations/Session/SessionWebSocketListener.cs b/Emby.Server.Implementations/Session/SessionWebSocketListener.cs index b3c93a904a..aba51de8f5 100644 --- a/Emby.Server.Implementations/Session/SessionWebSocketListener.cs +++ b/Emby.Server.Implementations/Session/SessionWebSocketListener.cs @@ -33,11 +33,6 @@ namespace Emby.Server.Implementations.Session /// private const float ForceKeepAliveFactor = 0.75f; - /// - /// Lock used for accessing the KeepAlive cancellation token. - /// - private readonly object _keepAliveLock = new object(); - /// /// The WebSocket watchlist. /// @@ -55,7 +50,7 @@ namespace Emby.Server.Implementations.Session /// /// The KeepAlive cancellation token. /// - private CancellationTokenSource? _keepAliveCancellationToken; + private System.Timers.Timer _keepAlive; /// /// Initializes a new instance of the class. @@ -71,12 +66,34 @@ namespace Emby.Server.Implementations.Session _logger = logger; _sessionManager = sessionManager; _loggerFactory = loggerFactory; + _keepAlive = new System.Timers.Timer(TimeSpan.FromSeconds(WebSocketLostTimeout * IntervalFactor)) + { + AutoReset = true, + Enabled = false + }; + _keepAlive.Elapsed += KeepAliveSockets; } /// public void Dispose() { - StopKeepAlive(); + if (_keepAlive is not null) + { + _keepAlive.Stop(); + _keepAlive.Elapsed -= KeepAliveSockets; + _keepAlive.Dispose(); + _keepAlive = null!; + } + + lock (_webSocketsLock) + { + foreach (var webSocket in _webSockets) + { + webSocket.Closed -= OnWebSocketClosed; + } + + _webSockets.Clear(); + } } /// @@ -164,7 +181,7 @@ namespace Emby.Server.Implementations.Session webSocket.Closed += OnWebSocketClosed; webSocket.LastKeepAliveDate = DateTime.UtcNow; - StartKeepAlive(); + _keepAlive.Start(); } // Notify WebSocket about timeout @@ -186,66 +203,26 @@ namespace Emby.Server.Implementations.Session { lock (_webSocketsLock) { - if (!_webSockets.Remove(webSocket)) - { - _logger.LogWarning("WebSocket {0} not on watchlist.", webSocket); - } - else + if (_webSockets.Remove(webSocket)) { webSocket.Closed -= OnWebSocketClosed; } - } - } - - /// - /// Starts the KeepAlive watcher. - /// - private void StartKeepAlive() - { - lock (_keepAliveLock) - { - if (_keepAliveCancellationToken is null) - { - _keepAliveCancellationToken = new CancellationTokenSource(); - // Start KeepAlive watcher - _ = RepeatAsyncCallbackEvery( - KeepAliveSockets, - TimeSpan.FromSeconds(WebSocketLostTimeout * IntervalFactor), - _keepAliveCancellationToken.Token); - } - } - } - - /// - /// Stops the KeepAlive watcher. - /// - private void StopKeepAlive() - { - lock (_keepAliveLock) - { - if (_keepAliveCancellationToken is not null) + else { - _keepAliveCancellationToken.Cancel(); - _keepAliveCancellationToken.Dispose(); - _keepAliveCancellationToken = null; + _logger.LogWarning("WebSocket {0} not on watchlist.", webSocket); } - } - lock (_webSocketsLock) - { - foreach (var webSocket in _webSockets) + if (_webSockets.Count == 0) { - webSocket.Closed -= OnWebSocketClosed; + _keepAlive.Stop(); } - - _webSockets.Clear(); } } /// /// Checks status of KeepAlive of WebSockets. /// - private async Task KeepAliveSockets() + private async void KeepAliveSockets(object? o, EventArgs? e) { List inactive; List lost; @@ -291,11 +268,6 @@ namespace Emby.Server.Implementations.Session RemoveWebSocket(webSocket); } } - - if (_webSockets.Count == 0) - { - StopKeepAlive(); - } } } @@ -310,29 +282,5 @@ namespace Emby.Server.Implementations.Session new ForceKeepAliveMessage(WebSocketLostTimeout), CancellationToken.None); } - - /// - /// Runs a given async callback once every specified interval time, until cancelled. - /// - /// The async callback. - /// The interval time. - /// The cancellation token. - /// Task. - private async Task RepeatAsyncCallbackEvery(Func callback, TimeSpan interval, CancellationToken cancellationToken) - { - while (!cancellationToken.IsCancellationRequested) - { - await callback().ConfigureAwait(false); - - try - { - await Task.Delay(interval, cancellationToken).ConfigureAwait(false); - } - catch (TaskCanceledException) - { - return; - } - } - } } } -- cgit v1.2.3