#pragma warning disable CS1591 using System; using System.Collections.Generic; using System.Net.WebSockets; using System.Threading.Tasks; using Emby.Server.Implementations.Session; using Jellyfin.Api.WebSocketListeners; using MediaBrowser.Controller; using MediaBrowser.Controller.Net; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging; namespace Emby.Server.Implementations.HttpServer { public class WebSocketManager : IWebSocketManager { private readonly IServerApplicationHost _appHost; private readonly ILogger _logger; private readonly ILoggerFactory _loggerFactory; private bool _disposed = false; public WebSocketManager( IServerApplicationHost appHost, ILogger logger, ILoggerFactory loggerFactory) { _appHost = appHost; _logger = logger; _loggerFactory = loggerFactory; } /// public async Task WebSocketRequestHandler(HttpContext context) { if (_disposed) { return; } var listener = _appHost.Resolve(); try { _logger.LogInformation("WS {IP} request", context.Connection.RemoteIpAddress); WebSocket webSocket = await context.WebSockets.AcceptWebSocketAsync().ConfigureAwait(false); using var connection = new WebSocketConnection( _loggerFactory.CreateLogger(), webSocket, context.Connection.RemoteIpAddress, context.Request.Query) { OnReceive = ProcessWebSocketMessageReceived }; listener?.ProcessWebSocketConnected(connection); await connection.ProcessAsync().ConfigureAwait(false); _logger.LogInformation("WS {IP} closed", context.Connection.RemoteIpAddress); } catch (Exception ex) // Otherwise ASP.Net will ignore the exception { _logger.LogError(ex, "WS {IP} WebSocketRequestHandler error", context.Connection.RemoteIpAddress); if (!context.Response.HasStarted) { context.Response.StatusCode = 500; } } } /// /// Processes the web socket message received. /// /// The result. private Task ProcessWebSocketMessageReceived(WebSocketMessageInfo result) { if (_disposed) { return Task.CompletedTask; } Parallel.Invoke( () => _appHost.Resolve(), () => _appHost.Resolve(), () => _appHost.Resolve()); return Task.CompletedTask; } } }