< Summary - Jellyfin

Information
Class: Jellyfin.Api.WebSocketListeners.SessionInfoWebSocketListener
Assembly: Jellyfin.Api
File(s): /srv/git/jellyfin/Jellyfin.Api/WebSocketListeners/SessionInfoWebSocketListener.cs
Line coverage
35%
Covered lines: 14
Uncovered lines: 25
Coverable lines: 39
Total lines: 145
Line coverage: 35.8%
Branch coverage
0%
Covered branches: 0
Total branches: 12
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Coverage history

Coverage history 0 25 50 75 100 10/25/2025 - 12:09:58 AM Line coverage: 36.8% (14/38) Branch coverage: 0% (0/12) Total lines: 1421/29/2026 - 12:13:32 AM Line coverage: 35.8% (14/39) Branch coverage: 0% (0/12) Total lines: 145 10/25/2025 - 12:09:58 AM Line coverage: 36.8% (14/38) Branch coverage: 0% (0/12) Total lines: 1421/29/2026 - 12:13:32 AM Line coverage: 35.8% (14/39) Branch coverage: 0% (0/12) Total lines: 145

Metrics

File(s)

/srv/git/jellyfin/Jellyfin.Api/WebSocketListeners/SessionInfoWebSocketListener.cs

#LineLine coverage
 1using System.Collections.Generic;
 2using System.Linq;
 3using System.Threading.Tasks;
 4using Jellyfin.Data;
 5using Jellyfin.Database.Implementations.Enums;
 6using MediaBrowser.Controller.Authentication;
 7using MediaBrowser.Controller.Library;
 8using MediaBrowser.Controller.Net;
 9using MediaBrowser.Controller.Session;
 10using MediaBrowser.Model.Dto;
 11using MediaBrowser.Model.Session;
 12using Microsoft.Extensions.Logging;
 13
 14namespace Jellyfin.Api.WebSocketListeners;
 15
 16/// <summary>
 17/// Class SessionInfoWebSocketListener.
 18/// </summary>
 19public class SessionInfoWebSocketListener : BasePeriodicWebSocketListener<IEnumerable<SessionInfoDto>, WebSocketListener
 20{
 21    private readonly ISessionManager _sessionManager;
 22    private bool _disposed;
 23
 24    /// <summary>
 25    /// Initializes a new instance of the <see cref="SessionInfoWebSocketListener"/> class.
 26    /// </summary>
 27    /// <param name="logger">Instance of the <see cref="ILogger{SessionInfoWebSocketListener}"/> interface.</param>
 28    /// <param name="sessionManager">Instance of the <see cref="ISessionManager"/> interface.</param>
 29    public SessionInfoWebSocketListener(ILogger<SessionInfoWebSocketListener> logger, ISessionManager sessionManager)
 1930        : base(logger)
 31    {
 1932        _sessionManager = sessionManager;
 33
 1934        _sessionManager.SessionStarted += OnSessionManagerSessionStarted;
 1935        _sessionManager.SessionEnded += OnSessionManagerSessionEnded;
 1936        _sessionManager.PlaybackStart += OnSessionManagerPlaybackStart;
 1937        _sessionManager.PlaybackStopped += OnSessionManagerPlaybackStopped;
 1938        _sessionManager.PlaybackProgress += OnSessionManagerPlaybackProgress;
 1939        _sessionManager.CapabilitiesChanged += OnSessionManagerCapabilitiesChanged;
 1940        _sessionManager.SessionActivity += OnSessionManagerSessionActivity;
 1941    }
 42
 43    /// <inheritdoc />
 044    protected override SessionMessageType Type => SessionMessageType.Sessions;
 45
 46    /// <inheritdoc />
 047    protected override SessionMessageType StartType => SessionMessageType.SessionsStart;
 48
 49    /// <inheritdoc />
 050    protected override SessionMessageType StopType => SessionMessageType.SessionsStop;
 51
 52    /// <summary>
 53    /// Gets the data to send.
 54    /// </summary>
 55    /// <returns>Task{SystemInfo}.</returns>
 56    protected override Task<IEnumerable<SessionInfoDto>> GetDataToSend()
 57    {
 058        return Task.FromResult(_sessionManager.Sessions.Select(_sessionManager.ToSessionInfoDto));
 59    }
 60
 61    /// <inheritdoc />
 62    protected override Task<IEnumerable<SessionInfoDto>> GetDataToSendForConnection(IWebSocketConnection connection)
 63    {
 064        var sessions = _sessionManager.Sessions;
 65
 66        // For non-admin users, filter the sessions to only include their own sessions
 067        if (connection.AuthorizationInfo?.User is not null &&
 068            !connection.AuthorizationInfo.IsApiKey &&
 069            !connection.AuthorizationInfo.User.HasPermission(PermissionKind.IsAdministrator))
 70        {
 071            var userId = connection.AuthorizationInfo.User.Id;
 072            sessions = sessions.Where(s => s.UserId.Equals(userId) || s.ContainsUser(userId));
 73        }
 74
 075        return Task.FromResult(sessions.Select(_sessionManager.ToSessionInfoDto));
 76    }
 77
 78    /// <inheritdoc />
 79    protected override async ValueTask DisposeAsyncCore()
 80    {
 81        if (!_disposed)
 82        {
 83            _sessionManager.SessionStarted -= OnSessionManagerSessionStarted;
 84            _sessionManager.SessionEnded -= OnSessionManagerSessionEnded;
 85            _sessionManager.PlaybackStart -= OnSessionManagerPlaybackStart;
 86            _sessionManager.PlaybackStopped -= OnSessionManagerPlaybackStopped;
 87            _sessionManager.PlaybackProgress -= OnSessionManagerPlaybackProgress;
 88            _sessionManager.CapabilitiesChanged -= OnSessionManagerCapabilitiesChanged;
 89            _sessionManager.SessionActivity -= OnSessionManagerSessionActivity;
 90            _disposed = true;
 91        }
 92
 93        await base.DisposeAsyncCore().ConfigureAwait(false);
 94    }
 95
 96    /// <summary>
 97    /// Starts sending messages over a session info web socket.
 98    /// </summary>
 99    /// <param name="message">The message.</param>
 100    protected override void Start(WebSocketMessageInfo message)
 101    {
 102        // Allow all authenticated users to subscribe to session information
 0103        if (message.Connection.AuthorizationInfo.User is null && !message.Connection.AuthorizationInfo.IsApiKey)
 104        {
 0105            throw new AuthenticationException("User must be authenticated to subscribe to session Information.");
 106        }
 107
 0108        base.Start(message);
 0109    }
 110
 111    private void OnSessionManagerSessionActivity(object? sender, SessionEventArgs e)
 112    {
 15113        SendData(false);
 15114    }
 115
 116    private void OnSessionManagerCapabilitiesChanged(object? sender, SessionEventArgs e)
 117    {
 0118        SendData(true);
 0119    }
 120
 121    private void OnSessionManagerPlaybackProgress(object? sender, PlaybackProgressEventArgs e)
 122    {
 0123        SendData(!e.IsAutomated);
 0124    }
 125
 126    private void OnSessionManagerPlaybackStopped(object? sender, PlaybackStopEventArgs e)
 127    {
 0128        SendData(true);
 0129    }
 130
 131    private void OnSessionManagerPlaybackStart(object? sender, PlaybackProgressEventArgs e)
 132    {
 0133        SendData(true);
 0134    }
 135
 136    private void OnSessionManagerSessionEnded(object? sender, SessionEventArgs e)
 137    {
 0138        SendData(true);
 0139    }
 140
 141    private void OnSessionManagerSessionStarted(object? sender, SessionEventArgs e)
 142    {
 15143        SendData(true);
 15144    }
 145}