using MediaBrowser.Common.Net; using MediaBrowser.Controller; using MediaBrowser.Controller.Session; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Net; using MediaBrowser.Model.Session; using MediaBrowser.Model.System; using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; namespace MediaBrowser.Server.Implementations.Session { public class WebSocketController : ISessionController { public SessionInfo Session { get; private set; } public List Sockets { get; private set; } private readonly IServerApplicationHost _appHost; public WebSocketController(SessionInfo session, IServerApplicationHost appHost) { Session = session; _appHost = appHost; Sockets = new List(); } public bool IsSessionActive { get { return Sockets.Any(i => i.State == WebSocketState.Open); } } private IWebSocketConnection GetActiveSocket() { var socket = Sockets .OrderByDescending(i => i.LastActivityDate) .FirstOrDefault(i => i.State == WebSocketState.Open); if (socket == null) { throw new InvalidOperationException("The requested session does not have an open web socket."); } return socket; } public Task SendPlayCommand(PlayRequest command, CancellationToken cancellationToken) { var socket = GetActiveSocket(); return socket.SendAsync(new WebSocketMessage { MessageType = "Play", Data = command }, cancellationToken); } public Task SendPlaystateCommand(PlaystateRequest command, CancellationToken cancellationToken) { var socket = GetActiveSocket(); return socket.SendAsync(new WebSocketMessage { MessageType = "Playstate", Data = command }, cancellationToken); } public Task SendLibraryUpdateInfo(LibraryUpdateInfo info, CancellationToken cancellationToken) { var socket = GetActiveSocket(); return socket.SendAsync(new WebSocketMessage { MessageType = "LibraryChanged", Data = info }, cancellationToken); } /// /// Sends the restart required message. /// /// The cancellation token. /// Task. public Task SendRestartRequiredNotification(CancellationToken cancellationToken) { var socket = GetActiveSocket(); return socket.SendAsync(new WebSocketMessage { MessageType = "RestartRequired", Data = _appHost.GetSystemInfo() }, cancellationToken); } /// /// Sends the user data change info. /// /// The info. /// The cancellation token. /// Task. public Task SendUserDataChangeInfo(UserDataChangeInfo info, CancellationToken cancellationToken) { var socket = GetActiveSocket(); return socket.SendAsync(new WebSocketMessage { MessageType = "UserDataChanged", Data = info }, cancellationToken); } /// /// Sends the server shutdown notification. /// /// The cancellation token. /// Task. public Task SendServerShutdownNotification(CancellationToken cancellationToken) { var socket = GetActiveSocket(); return socket.SendAsync(new WebSocketMessage { MessageType = "ServerShuttingDown", Data = string.Empty }, cancellationToken); } /// /// Sends the server restart notification. /// /// The cancellation token. /// Task. public Task SendServerRestartNotification(CancellationToken cancellationToken) { var socket = GetActiveSocket(); return socket.SendAsync(new WebSocketMessage { MessageType = "ServerRestarting", Data = string.Empty }, cancellationToken); } public Task SendGeneralCommand(GeneralCommand command, CancellationToken cancellationToken) { var socket = GetActiveSocket(); return socket.SendAsync(new WebSocketMessage { MessageType = "GeneralCommand", Data = command }, cancellationToken); } public Task SendSessionEndedNotification(SessionInfoDto sessionInfo, CancellationToken cancellationToken) { var socket = GetActiveSocket(); return socket.SendAsync(new WebSocketMessage { MessageType = "SessionEnded", Data = sessionInfo }, cancellationToken); } public Task SendPlaybackStartNotification(SessionInfoDto sessionInfo, CancellationToken cancellationToken) { var socket = GetActiveSocket(); return socket.SendAsync(new WebSocketMessage { MessageType = "PlaybackStart", Data = sessionInfo }, cancellationToken); } public Task SendPlaybackStoppedNotification(SessionInfoDto sessionInfo, CancellationToken cancellationToken) { var socket = GetActiveSocket(); return socket.SendAsync(new WebSocketMessage { MessageType = "PlaybackStopped", Data = sessionInfo }, cancellationToken); } } }