Close sessions for lost WebSockets to prevent zombie SyncPlay groups (#17079)
Close sessions for lost WebSockets to prevent zombie SyncPlay groups
This commit is contained in:
@@ -127,8 +127,12 @@ namespace Emby.Server.Implementations.HttpServer
|
||||
{
|
||||
receiveResult = await _socket.ReceiveAsync(memory, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
catch (WebSocketException ex)
|
||||
catch (Exception ex) when (ex is WebSocketException or ObjectDisposedException or OperationCanceledException)
|
||||
{
|
||||
// ObjectDisposedException/OperationCanceledException: the socket was torn
|
||||
// down underneath us (e.g. by the keep-alive watchdog after the connection
|
||||
// was declared lost). Fall through so Closed is still raised and the
|
||||
// session can release this connection.
|
||||
_logger.LogWarning("WS {IP} error receiving data: {Message}", RemoteEndPoint, ex.Message);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -246,8 +246,21 @@ namespace Emby.Server.Implementations.Session
|
||||
_logger.LogInformation("Lost {0} WebSockets.", lost.Count);
|
||||
foreach (var webSocket in lost)
|
||||
{
|
||||
// TODO: handle session relative to the lost webSocket
|
||||
RemoveWebSocket(webSocket);
|
||||
|
||||
// The connection stopped answering keep-alives, so a close frame will
|
||||
// never arrive and the pending receive loop would hang forever, keeping
|
||||
// the session (and e.g. its SyncPlay group membership) alive. Disposing
|
||||
// the connection aborts the receive loop, which raises Closed and lets
|
||||
// the session end normally.
|
||||
try
|
||||
{
|
||||
webSocket.Dispose();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_logger.LogWarning(exception, "Error disposing lost WebSocket from {RemoteEndPoint}.", webSocket.RemoteEndPoint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user