< Summary - Jellyfin

Information
Class: Emby.Server.Implementations.HttpServer.WebSocketManager
Assembly: Emby.Server.Implementations
File(s): /srv/git/jellyfin/Emby.Server.Implementations/HttpServer/WebSocketManager.cs
Line coverage
55%
Covered lines: 5
Uncovered lines: 4
Coverable lines: 9
Total lines: 98
Line coverage: 55.5%
Branch coverage
0%
Covered branches: 0
Total branches: 2
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Coverage history

Coverage history 0 25 50 75 100

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
ProcessWebSocketMessageReceived(...)0%620%

File(s)

/srv/git/jellyfin/Emby.Server.Implementations/HttpServer/WebSocketManager.cs

#LineLine coverage
 1#nullable disable
 2
 3#pragma warning disable CS1591
 4
 5using System;
 6using System.Collections.Generic;
 7using System.Linq;
 8using System.Net.WebSockets;
 9using System.Threading.Tasks;
 10using MediaBrowser.Common.Extensions;
 11using MediaBrowser.Controller.Net;
 12using Microsoft.AspNetCore.Http;
 13using Microsoft.Extensions.Logging;
 14
 15namespace Emby.Server.Implementations.HttpServer
 16{
 17    public class WebSocketManager : IWebSocketManager
 18    {
 19        private readonly IWebSocketListener[] _webSocketListeners;
 20        private readonly IAuthService _authService;
 21        private readonly ILogger<WebSocketManager> _logger;
 22        private readonly ILoggerFactory _loggerFactory;
 23
 24        public WebSocketManager(
 25            IAuthService authService,
 26            IEnumerable<IWebSocketListener> webSocketListeners,
 27            ILogger<WebSocketManager> logger,
 28            ILoggerFactory loggerFactory)
 29        {
 2030            _webSocketListeners = webSocketListeners.ToArray();
 2031            _authService = authService;
 2032            _logger = logger;
 2033            _loggerFactory = loggerFactory;
 2034        }
 35
 36        /// <inheritdoc />
 37        public async Task WebSocketRequestHandler(HttpContext context)
 38        {
 39            var authorizationInfo = await _authService.Authenticate(context.Request).ConfigureAwait(false);
 40            if (!authorizationInfo.IsAuthenticated)
 41            {
 42                throw new SecurityException("Token is required");
 43            }
 44
 45            try
 46            {
 47                _logger.LogInformation("WS {IP} request", context.Connection.RemoteIpAddress);
 48
 49                WebSocket webSocket = await context.WebSockets.AcceptWebSocketAsync().ConfigureAwait(false);
 50
 51                var connection = new WebSocketConnection(
 52                    _loggerFactory.CreateLogger<WebSocketConnection>(),
 53                    webSocket,
 54                    authorizationInfo,
 55                    context.GetNormalizedRemoteIP())
 56                {
 57                    OnReceive = ProcessWebSocketMessageReceived
 58                };
 59                await using (connection.ConfigureAwait(false))
 60                {
 61                    var tasks = new Task[_webSocketListeners.Length];
 62                    for (var i = 0; i < _webSocketListeners.Length; ++i)
 63                    {
 64                        tasks[i] = _webSocketListeners[i].ProcessWebSocketConnectedAsync(connection, context);
 65                    }
 66
 67                    await Task.WhenAll(tasks).ConfigureAwait(false);
 68
 69                    await connection.ReceiveAsync().ConfigureAwait(false);
 70                    _logger.LogInformation("WS {IP} closed", context.Connection.RemoteIpAddress);
 71                }
 72            }
 73            catch (Exception ex) // Otherwise ASP.Net will ignore the exception
 74            {
 75                _logger.LogError(ex, "WS {IP} WebSocketRequestHandler error", context.Connection.RemoteIpAddress);
 76                if (!context.Response.HasStarted)
 77                {
 78                    context.Response.StatusCode = 500;
 79                }
 80            }
 81        }
 82
 83        /// <summary>
 84        /// Processes the web socket message received.
 85        /// </summary>
 86        /// <param name="result">The result.</param>
 87        private Task ProcessWebSocketMessageReceived(WebSocketMessageInfo result)
 88        {
 089            var tasks = new Task[_webSocketListeners.Length];
 090            for (var i = 0; i < _webSocketListeners.Length; ++i)
 91            {
 092                tasks[i] = _webSocketListeners[i].ProcessMessageAsync(result);
 93            }
 94
 095            return Task.WhenAll(tasks);
 96        }
 97    }
 98}