|
|
|
@ -22,17 +22,17 @@ namespace Emby.Server.Implementations.Session
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// The timeout in seconds after which a WebSocket is considered to be lost.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public readonly int WebSocketLostTimeout = 60;
|
|
|
|
|
public const int WebSocketLostTimeout = 60;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// The keep-alive interval factor; controls how often the watcher will check on the status of the WebSockets.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public readonly double IntervalFactor = 0.2;
|
|
|
|
|
public const float IntervalFactor = 0.2f;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// The ForceKeepAlive factor; controls when a ForceKeepAlive is sent.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public readonly double ForceKeepAliveFactor = 0.75;
|
|
|
|
|
public const float ForceKeepAliveFactor = 0.75f;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// The _session manager
|
|
|
|
@ -213,7 +213,7 @@ namespace Emby.Server.Implementations.Session
|
|
|
|
|
{
|
|
|
|
|
_keepAliveCancellationToken = new CancellationTokenSource();
|
|
|
|
|
// Start KeepAlive watcher
|
|
|
|
|
var task = RepeatAsyncCallbackEvery(
|
|
|
|
|
_ = RepeatAsyncCallbackEvery(
|
|
|
|
|
KeepAliveSockets,
|
|
|
|
|
TimeSpan.FromSeconds(WebSocketLostTimeout * IntervalFactor),
|
|
|
|
|
_keepAliveCancellationToken.Token);
|
|
|
|
@ -241,6 +241,7 @@ namespace Emby.Server.Implementations.Session
|
|
|
|
|
{
|
|
|
|
|
webSocket.Closed -= OnWebSocketClosed;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_webSockets.Clear();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -250,8 +251,8 @@ namespace Emby.Server.Implementations.Session
|
|
|
|
|
/// </summary>
|
|
|
|
|
private async Task KeepAliveSockets()
|
|
|
|
|
{
|
|
|
|
|
IEnumerable<IWebSocketConnection> inactive;
|
|
|
|
|
IEnumerable<IWebSocketConnection> lost;
|
|
|
|
|
List<IWebSocketConnection> inactive;
|
|
|
|
|
List<IWebSocketConnection> lost;
|
|
|
|
|
|
|
|
|
|
lock (_webSocketsLock)
|
|
|
|
|
{
|
|
|
|
@ -261,8 +262,8 @@ namespace Emby.Server.Implementations.Session
|
|
|
|
|
{
|
|
|
|
|
var elapsed = (DateTime.UtcNow - i.LastKeepAliveDate).TotalSeconds;
|
|
|
|
|
return (elapsed > WebSocketLostTimeout * ForceKeepAliveFactor) && (elapsed < WebSocketLostTimeout);
|
|
|
|
|
});
|
|
|
|
|
lost = _webSockets.Where(i => (DateTime.UtcNow - i.LastKeepAliveDate).TotalSeconds >= WebSocketLostTimeout);
|
|
|
|
|
}).ToList();
|
|
|
|
|
lost = _webSockets.Where(i => (DateTime.UtcNow - i.LastKeepAliveDate).TotalSeconds >= WebSocketLostTimeout).ToList();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (inactive.Any())
|
|
|
|
@ -279,7 +280,7 @@ namespace Emby.Server.Implementations.Session
|
|
|
|
|
catch (WebSocketException exception)
|
|
|
|
|
{
|
|
|
|
|
_logger.LogInformation(exception, "Error sending ForceKeepAlive message to WebSocket.");
|
|
|
|
|
lost = lost.Append(webSocket);
|
|
|
|
|
lost.Add(webSocket);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -288,7 +289,7 @@ namespace Emby.Server.Implementations.Session
|
|
|
|
|
if (lost.Any())
|
|
|
|
|
{
|
|
|
|
|
_logger.LogInformation("Lost {0} WebSockets.", lost.Count());
|
|
|
|
|
foreach (var webSocket in lost.ToList())
|
|
|
|
|
foreach (var webSocket in lost)
|
|
|
|
|
{
|
|
|
|
|
// TODO: handle session relative to the lost webSocket
|
|
|
|
|
RemoveWebSocket(webSocket);
|
|
|
|
|