mirror of
https://github.com/SoPat712/allstarr.git
synced 2026-02-09 23:55:10 -05:00
Integrate WebSocket proxy with session manager to cleanup sessions on client disconnect
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
using System.Net.WebSockets;
|
using System.Net.WebSockets;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using allstarr.Models.Settings;
|
using allstarr.Models.Settings;
|
||||||
|
using allstarr.Services.Jellyfin;
|
||||||
|
|
||||||
namespace allstarr.Middleware;
|
namespace allstarr.Middleware;
|
||||||
|
|
||||||
@@ -13,15 +14,18 @@ public class WebSocketProxyMiddleware
|
|||||||
private readonly RequestDelegate _next;
|
private readonly RequestDelegate _next;
|
||||||
private readonly JellyfinSettings _settings;
|
private readonly JellyfinSettings _settings;
|
||||||
private readonly ILogger<WebSocketProxyMiddleware> _logger;
|
private readonly ILogger<WebSocketProxyMiddleware> _logger;
|
||||||
|
private readonly JellyfinSessionManager _sessionManager;
|
||||||
|
|
||||||
public WebSocketProxyMiddleware(
|
public WebSocketProxyMiddleware(
|
||||||
RequestDelegate next,
|
RequestDelegate next,
|
||||||
IOptions<JellyfinSettings> settings,
|
IOptions<JellyfinSettings> settings,
|
||||||
ILogger<WebSocketProxyMiddleware> logger)
|
ILogger<WebSocketProxyMiddleware> logger,
|
||||||
|
JellyfinSessionManager sessionManager)
|
||||||
{
|
{
|
||||||
_next = next;
|
_next = next;
|
||||||
_settings = settings.Value;
|
_settings = settings.Value;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
|
_sessionManager = sessionManager;
|
||||||
|
|
||||||
_logger.LogDebug("🔧 WEBSOCKET: WebSocketProxyMiddleware initialized - Jellyfin URL: {Url}", _settings.Url);
|
_logger.LogDebug("🔧 WEBSOCKET: WebSocketProxyMiddleware initialized - Jellyfin URL: {Url}", _settings.Url);
|
||||||
}
|
}
|
||||||
@@ -65,9 +69,31 @@ public class WebSocketProxyMiddleware
|
|||||||
{
|
{
|
||||||
ClientWebSocket? serverWebSocket = null;
|
ClientWebSocket? serverWebSocket = null;
|
||||||
WebSocket? clientWebSocket = null;
|
WebSocket? clientWebSocket = null;
|
||||||
|
string? deviceId = null;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
// Extract device ID from query string or headers for session tracking
|
||||||
|
deviceId = context.Request.Query["deviceId"].ToString();
|
||||||
|
if (string.IsNullOrEmpty(deviceId))
|
||||||
|
{
|
||||||
|
// Try to extract from X-Emby-Authorization header
|
||||||
|
if (context.Request.Headers.TryGetValue("X-Emby-Authorization", out var authHeader))
|
||||||
|
{
|
||||||
|
var authValue = authHeader.ToString();
|
||||||
|
var deviceIdMatch = System.Text.RegularExpressions.Regex.Match(authValue, @"DeviceId=""([^""]+)""");
|
||||||
|
if (deviceIdMatch.Success)
|
||||||
|
{
|
||||||
|
deviceId = deviceIdMatch.Groups[1].Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(deviceId))
|
||||||
|
{
|
||||||
|
_logger.LogDebug("🔍 WEBSOCKET: Client WebSocket for device {DeviceId}", deviceId);
|
||||||
|
}
|
||||||
|
|
||||||
// Accept the WebSocket connection from the client
|
// Accept the WebSocket connection from the client
|
||||||
clientWebSocket = await context.WebSockets.AcceptWebSocketAsync();
|
clientWebSocket = await context.WebSockets.AcceptWebSocketAsync();
|
||||||
_logger.LogDebug("✓ WEBSOCKET: Client WebSocket accepted");
|
_logger.LogDebug("✓ WEBSOCKET: Client WebSocket accepted");
|
||||||
@@ -96,9 +122,9 @@ public class WebSocketProxyMiddleware
|
|||||||
serverWebSocket.Options.SetRequestHeader("X-Emby-Authorization", embyAuthHeader.ToString());
|
serverWebSocket.Options.SetRequestHeader("X-Emby-Authorization", embyAuthHeader.ToString());
|
||||||
_logger.LogDebug("🔑 WEBSOCKET: Forwarded X-Emby-Authorization header");
|
_logger.LogDebug("🔑 WEBSOCKET: Forwarded X-Emby-Authorization header");
|
||||||
}
|
}
|
||||||
else if (context.Request.Headers.TryGetValue("Authorization", out var authHeader))
|
else if (context.Request.Headers.TryGetValue("Authorization", out var authHeader2))
|
||||||
{
|
{
|
||||||
var authValue = authHeader.ToString();
|
var authValue = authHeader2.ToString();
|
||||||
// If it's a MediaBrowser auth header, use X-Emby-Authorization
|
// If it's a MediaBrowser auth header, use X-Emby-Authorization
|
||||||
if (authValue.Contains("MediaBrowser", StringComparison.OrdinalIgnoreCase))
|
if (authValue.Contains("MediaBrowser", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
@@ -165,6 +191,13 @@ public class WebSocketProxyMiddleware
|
|||||||
clientWebSocket?.Dispose();
|
clientWebSocket?.Dispose();
|
||||||
serverWebSocket?.Dispose();
|
serverWebSocket?.Dispose();
|
||||||
|
|
||||||
|
// CRITICAL: Notify session manager that client disconnected
|
||||||
|
if (!string.IsNullOrEmpty(deviceId))
|
||||||
|
{
|
||||||
|
_logger.LogInformation("🧹 WEBSOCKET: Client disconnected, removing session for device {DeviceId}", deviceId);
|
||||||
|
await _sessionManager.RemoveSessionAsync(deviceId);
|
||||||
|
}
|
||||||
|
|
||||||
_logger.LogDebug("🧹 WEBSOCKET: WebSocket connections cleaned up");
|
_logger.LogDebug("🧹 WEBSOCKET: WebSocket connections cleaned up");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user