From eb72c2db513f5306eecccb94f0f1cd5296a7d7db Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 2 Oct 2013 21:22:50 -0400 Subject: [PATCH] updated nuget --- MediaBrowser.Common/Net/IServerManager.cs | 11 - .../Net/IWebSocketConnection.cs | 6 + .../Session/ISessionController.cs | 46 ++- .../Session/ISessionManager.cs | 13 +- .../Session/SessionInfo.cs | 29 +- MediaBrowser.Model/Querying/ItemQuery.cs | 18 ++ .../EntryPoints/LibraryChangedNotifier.cs | 47 ++- .../EntryPoints/WebSocketEvents.cs | 9 +- .../ServerManager/ServerManager.cs | 2 +- .../ServerManager/WebSocketConnection.cs | 7 + .../Session/SessionManager.cs | 54 ++-- .../Session/SessionWebSocketListener.cs | 284 +++++++++++------- .../Session/WebSocketController.cs | 85 +++++- .../ApplicationHost.cs | 2 - .../Native/BrowserLauncher.cs | 2 +- Nuget/MediaBrowser.Common.Internal.nuspec | 4 +- Nuget/MediaBrowser.Common.nuspec | 2 +- Nuget/MediaBrowser.Server.Core.nuspec | 4 +- 18 files changed, 390 insertions(+), 235 deletions(-) diff --git a/MediaBrowser.Common/Net/IServerManager.cs b/MediaBrowser.Common/Net/IServerManager.cs index 32be88a34..6965677bb 100644 --- a/MediaBrowser.Common/Net/IServerManager.cs +++ b/MediaBrowser.Common/Net/IServerManager.cs @@ -62,17 +62,6 @@ namespace MediaBrowser.Common.Net /// messageType Task SendWebSocketMessageAsync(string messageType, Func dataFunction, CancellationToken cancellationToken); - /// - /// Sends the web socket message async. - /// - /// - /// Type of the message. - /// The data function. - /// The connections. - /// The cancellation token. - /// Task. - Task SendWebSocketMessageAsync(string messageType, Func dataFunction, IEnumerable connections, CancellationToken cancellationToken); - /// /// Adds the web socket listeners. /// diff --git a/MediaBrowser.Common/Net/IWebSocketConnection.cs b/MediaBrowser.Common/Net/IWebSocketConnection.cs index 434b8ff5c..482da131e 100644 --- a/MediaBrowser.Common/Net/IWebSocketConnection.cs +++ b/MediaBrowser.Common/Net/IWebSocketConnection.cs @@ -7,6 +7,12 @@ namespace MediaBrowser.Common.Net { public interface IWebSocketConnection : IDisposable { + /// + /// Gets the id. + /// + /// The id. + Guid Id { get; } + /// /// Gets the last activity date. /// diff --git a/MediaBrowser.Controller/Session/ISessionController.cs b/MediaBrowser.Controller/Session/ISessionController.cs index f37d63b72..597a14cc6 100644 --- a/MediaBrowser.Controller/Session/ISessionController.cs +++ b/MediaBrowser.Controller/Session/ISessionController.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Model.Session; +using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Session; using System.Threading; using System.Threading.Tasks; @@ -7,55 +8,70 @@ namespace MediaBrowser.Controller.Session public interface ISessionController { /// - /// Supportses the specified session. + /// Gets a value indicating whether [supports media remote control]. /// - /// The session. - /// true if XXXX, false otherwise - bool Supports(SessionInfo session); + /// true if [supports media remote control]; otherwise, false. + bool SupportsMediaRemoteControl { get; } + + /// + /// Gets a value indicating whether this instance is session active. + /// + /// true if this instance is session active; otherwise, false. + bool IsSessionActive { get; } /// /// Sends the system command. /// - /// The session. /// The command. /// The cancellation token. /// Task. - Task SendSystemCommand(SessionInfo session, SystemCommand command, CancellationToken cancellationToken); + Task SendSystemCommand(SystemCommand command, CancellationToken cancellationToken); /// /// Sends the message command. /// - /// The session. /// The command. /// The cancellation token. /// Task. - Task SendMessageCommand(SessionInfo session, MessageCommand command, CancellationToken cancellationToken); + Task SendMessageCommand(MessageCommand command, CancellationToken cancellationToken); /// /// Sends the play command. /// - /// The session. /// The command. /// The cancellation token. /// Task. - Task SendPlayCommand(SessionInfo session, PlayRequest command, CancellationToken cancellationToken); + Task SendPlayCommand(PlayRequest command, CancellationToken cancellationToken); /// /// Sends the browse command. /// - /// The session. /// The command. /// The cancellation token. /// Task. - Task SendBrowseCommand(SessionInfo session, BrowseRequest command, CancellationToken cancellationToken); + Task SendBrowseCommand(BrowseRequest command, CancellationToken cancellationToken); /// /// Sends the playstate command. /// - /// The session. /// The command. /// The cancellation token. /// Task. - Task SendPlaystateCommand(SessionInfo session, PlaystateRequest command, CancellationToken cancellationToken); + Task SendPlaystateCommand(PlaystateRequest command, CancellationToken cancellationToken); + + /// + /// Sends the library update info. + /// + /// The info. + /// The cancellation token. + /// Task. + Task SendLibraryUpdateInfo(LibraryUpdateInfo info, CancellationToken cancellationToken); + + /// + /// Sends the restart required message. + /// + /// The cancellation token. + /// Task. + Task SendRestartRequiredMessage(CancellationToken cancellationToken); } } diff --git a/MediaBrowser.Controller/Session/ISessionManager.cs b/MediaBrowser.Controller/Session/ISessionManager.cs index 6ee57eb46..b2d111e54 100644 --- a/MediaBrowser.Controller/Session/ISessionManager.cs +++ b/MediaBrowser.Controller/Session/ISessionManager.cs @@ -13,12 +13,6 @@ namespace MediaBrowser.Controller.Session /// public interface ISessionManager { - /// - /// Adds the parts. - /// - /// The remote controllers. - void AddParts(IEnumerable remoteControllers); - /// /// Occurs when [playback start]. /// @@ -119,5 +113,12 @@ namespace MediaBrowser.Controller.Session /// The cancellation token. /// Task. Task SendPlaystateCommand(Guid sessionId, PlaystateRequest command, CancellationToken cancellationToken); + + /// + /// Sends the restart required message. + /// + /// The cancellation token. + /// Task. + Task SendRestartRequiredMessage(CancellationToken cancellationToken); } } \ No newline at end of file diff --git a/MediaBrowser.Controller/Session/SessionInfo.cs b/MediaBrowser.Controller/Session/SessionInfo.cs index d50f19c1f..ed2fcda67 100644 --- a/MediaBrowser.Controller/Session/SessionInfo.cs +++ b/MediaBrowser.Controller/Session/SessionInfo.cs @@ -1,9 +1,6 @@ -using MediaBrowser.Common.Net; -using MediaBrowser.Controller.Entities; -using MediaBrowser.Model.Net; +using MediaBrowser.Controller.Entities; using System; using System.Collections.Generic; -using System.Linq; namespace MediaBrowser.Controller.Session { @@ -14,7 +11,6 @@ namespace MediaBrowser.Controller.Session { public SessionInfo() { - WebSockets = new List(); QueueableMediaTypes = new List(); } @@ -114,18 +110,18 @@ namespace MediaBrowser.Controller.Session /// The device id. public string DeviceId { get; set; } - /// - /// Gets or sets the web socket. - /// - /// The web socket. - public List WebSockets { get; set; } - /// /// Gets or sets the application version. /// /// The application version. public string ApplicationVersion { get; set; } + /// + /// Gets or sets the session controller. + /// + /// The session controller. + public ISessionController SessionController { get; set; } + /// /// Gets a value indicating whether this instance is active. /// @@ -134,9 +130,9 @@ namespace MediaBrowser.Controller.Session { get { - if (WebSockets.Count > 0) + if (SessionController != null) { - return WebSockets.Any(i => i.State == WebSocketState.Open); + return SessionController.IsSessionActive; } return (DateTime.UtcNow - LastActivityDate).TotalMinutes <= 10; @@ -151,7 +147,12 @@ namespace MediaBrowser.Controller.Session { get { - return WebSockets.Any(i => i.State == WebSocketState.Open); + if (SessionController != null) + { + return SessionController.SupportsMediaRemoteControl; + } + + return false; } } } diff --git a/MediaBrowser.Model/Querying/ItemQuery.cs b/MediaBrowser.Model/Querying/ItemQuery.cs index 69c79104a..20eac55e8 100644 --- a/MediaBrowser.Model/Querying/ItemQuery.cs +++ b/MediaBrowser.Model/Querying/ItemQuery.cs @@ -206,6 +206,24 @@ namespace MediaBrowser.Model.Querying /// The parent index number. public int? ParentIndexNumber { get; set; } + /// + /// Gets or sets the min players. + /// + /// The min players. + public int? MinPlayers { get; set; } + + /// + /// Gets or sets the name starts with or greater. + /// + /// The name starts with or greater. + public string NameStartsWithOrGreater { get; set; } + + /// + /// Gets or sets the album artist starts with or greater. + /// + /// The album artist starts with or greater. + public string AlbumArtistStartsWithOrGreater { get; set; } + /// /// Initializes a new instance of the class. /// diff --git a/MediaBrowser.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs b/MediaBrowser.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs index 1306017ca..7a3081ab5 100644 --- a/MediaBrowser.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs +++ b/MediaBrowser.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs @@ -1,5 +1,4 @@ -using MediaBrowser.Common.Net; -using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Plugins; using MediaBrowser.Controller.Session; @@ -21,7 +20,6 @@ namespace MediaBrowser.Server.Implementations.EntryPoints private readonly ILibraryManager _libraryManager; private readonly ISessionManager _sessionManager; - private readonly IServerManager _serverManager; private readonly IUserManager _userManager; private readonly ILogger _logger; @@ -48,11 +46,10 @@ namespace MediaBrowser.Server.Implementations.EntryPoints /// private const int LibraryUpdateDuration = 20000; - public LibraryChangedNotifier(ILibraryManager libraryManager, ISessionManager sessionManager, IServerManager serverManager, IUserManager userManager, ILogger logger) + public LibraryChangedNotifier(ILibraryManager libraryManager, ISessionManager sessionManager, IUserManager userManager, ILogger logger) { _libraryManager = libraryManager; _sessionManager = sessionManager; - _serverManager = serverManager; _userManager = userManager; _logger = logger; } @@ -187,31 +184,33 @@ namespace MediaBrowser.Server.Implementations.EntryPoints /// The folders added to. /// The folders removed from. /// The cancellation token. - private async void SendChangeNotifications(IEnumerable itemsAdded, IEnumerable itemsUpdated, IEnumerable itemsRemoved, IEnumerable foldersAddedTo, IEnumerable foldersRemovedFrom, CancellationToken cancellationToken) + private async void SendChangeNotifications(List itemsAdded, List itemsUpdated, List itemsRemoved, List foldersAddedTo, List foldersRemovedFrom, CancellationToken cancellationToken) { - var currentSessions = _sessionManager.Sessions.ToList(); - - var users = currentSessions.Select(i => i.User) - .Where(i => i != null) - .Select(i => i.Id) - .Distinct() - .ToList(); - - foreach (var userId in users) + foreach (var user in _userManager.Users.ToList()) { - var id = userId; - var webSockets = currentSessions.Where(u => u.User != null && u.User.Id == id) - .SelectMany(i => i.WebSockets) + var id = user.Id; + var userSessions = _sessionManager.Sessions + .Where(u => u.User != null && u.User.Id == id && u.SessionController != null && u.IsActive) .ToList(); - try + if (userSessions.Count > 0) { - await _serverManager.SendWebSocketMessageAsync("LibraryChanged", () => GetLibraryUpdateInfo(itemsAdded, itemsUpdated, itemsRemoved, foldersAddedTo, foldersRemovedFrom, id), webSockets, cancellationToken).ConfigureAwait(false); - } - catch (Exception ex) - { - _logger.ErrorException("Error sending LibraryChanged message", ex); + var info = GetLibraryUpdateInfo(itemsAdded, itemsUpdated, itemsRemoved, foldersAddedTo, + foldersRemovedFrom, id); + + foreach (var userSession in userSessions) + { + try + { + await userSession.SessionController.SendLibraryUpdateInfo(info, cancellationToken).ConfigureAwait(false); + } + catch (Exception ex) + { + _logger.ErrorException("Error sending LibraryChanged message", ex); + } + } } + } } diff --git a/MediaBrowser.Server.Implementations/EntryPoints/WebSocketEvents.cs b/MediaBrowser.Server.Implementations/EntryPoints/WebSocketEvents.cs index 29372a40a..4349b6976 100644 --- a/MediaBrowser.Server.Implementations/EntryPoints/WebSocketEvents.cs +++ b/MediaBrowser.Server.Implementations/EntryPoints/WebSocketEvents.cs @@ -8,8 +8,10 @@ using MediaBrowser.Controller.Dto; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Plugins; +using MediaBrowser.Controller.Session; using MediaBrowser.Model.Tasks; using System; +using System.Threading; namespace MediaBrowser.Server.Implementations.EntryPoints { @@ -45,13 +47,15 @@ namespace MediaBrowser.Server.Implementations.EntryPoints private readonly IDtoService _dtoService; + private ISessionManager _sessionManager; + /// /// Initializes a new instance of the class. /// /// The server manager. /// The logger. /// The user manager. - public WebSocketEvents(IServerManager serverManager, IServerApplicationHost appHost, IUserManager userManager, IInstallationManager installationManager, ITaskManager taskManager, IDtoService dtoService) + public WebSocketEvents(IServerManager serverManager, IServerApplicationHost appHost, IUserManager userManager, IInstallationManager installationManager, ITaskManager taskManager, IDtoService dtoService, ISessionManager sessionManager) { _serverManager = serverManager; _userManager = userManager; @@ -59,6 +63,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints _appHost = appHost; _taskManager = taskManager; _dtoService = dtoService; + _sessionManager = sessionManager; } public void Run() @@ -126,7 +131,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints /// The instance containing the event data. void kernel_HasPendingRestartChanged(object sender, EventArgs e) { - _serverManager.SendWebSocketMessage("RestartRequired", _appHost.GetSystemInfo()); + _sessionManager.SendRestartRequiredMessage(CancellationToken.None); } /// diff --git a/MediaBrowser.Server.Implementations/ServerManager/ServerManager.cs b/MediaBrowser.Server.Implementations/ServerManager/ServerManager.cs index a840ae214..638e6fa0d 100644 --- a/MediaBrowser.Server.Implementations/ServerManager/ServerManager.cs +++ b/MediaBrowser.Server.Implementations/ServerManager/ServerManager.cs @@ -273,7 +273,7 @@ namespace MediaBrowser.Server.Implementations.ServerManager /// dataFunction /// or /// cancellationToken - public async Task SendWebSocketMessageAsync(string messageType, Func dataFunction, IEnumerable connections, CancellationToken cancellationToken) + private async Task SendWebSocketMessageAsync(string messageType, Func dataFunction, IEnumerable connections, CancellationToken cancellationToken) { if (string.IsNullOrEmpty(messageType)) { diff --git a/MediaBrowser.Server.Implementations/ServerManager/WebSocketConnection.cs b/MediaBrowser.Server.Implementations/ServerManager/WebSocketConnection.cs index 4bab10ee0..61c06ba6d 100644 --- a/MediaBrowser.Server.Implementations/ServerManager/WebSocketConnection.cs +++ b/MediaBrowser.Server.Implementations/ServerManager/WebSocketConnection.cs @@ -56,6 +56,12 @@ namespace MediaBrowser.Server.Implementations.ServerManager /// The last activity date. public DateTime LastActivityDate { get; private set; } + /// + /// Gets the id. + /// + /// The id. + public Guid Id { get; private set; } + /// /// Initializes a new instance of the class. /// @@ -83,6 +89,7 @@ namespace MediaBrowser.Server.Implementations.ServerManager throw new ArgumentNullException("logger"); } + Id = Guid.NewGuid(); _jsonSerializer = jsonSerializer; _socket = socket; _socket.OnReceiveBytes = OnReceiveInternal; diff --git a/MediaBrowser.Server.Implementations/Session/SessionManager.cs b/MediaBrowser.Server.Implementations/Session/SessionManager.cs index efb8dbe10..ac69b0dc5 100644 --- a/MediaBrowser.Server.Implementations/Session/SessionManager.cs +++ b/MediaBrowser.Server.Implementations/Session/SessionManager.cs @@ -78,12 +78,6 @@ namespace MediaBrowser.Server.Implementations.Session _userRepository = userRepository; } - private List _remoteControllers; - public void AddParts(IEnumerable remoteControllers) - { - _remoteControllers = remoteControllers.ToList(); - } - /// /// Gets all connections. /// @@ -433,18 +427,8 @@ namespace MediaBrowser.Server.Implementations.Session { throw new ArgumentException(string.Format("Session {0} does not support remote control.", session.Id)); } - - return session; - } - /// - /// Gets the controllers. - /// - /// The session. - /// IEnumerable{ISessionRemoteController}. - private IEnumerable GetControllers(SessionInfo session) - { - return _remoteControllers.Where(i => i.Supports(session)); + return session; } /// @@ -458,9 +442,7 @@ namespace MediaBrowser.Server.Implementations.Session { var session = GetSessionForRemoteControl(sessionId); - var tasks = GetControllers(session).Select(i => i.SendSystemCommand(session, command, cancellationToken)); - - return Task.WhenAll(tasks); + return session.SessionController.SendSystemCommand(command, cancellationToken); } /// @@ -474,9 +456,7 @@ namespace MediaBrowser.Server.Implementations.Session { var session = GetSessionForRemoteControl(sessionId); - var tasks = GetControllers(session).Select(i => i.SendMessageCommand(session, command, cancellationToken)); - - return Task.WhenAll(tasks); + return session.SessionController.SendMessageCommand(command, cancellationToken); } /// @@ -490,9 +470,7 @@ namespace MediaBrowser.Server.Implementations.Session { var session = GetSessionForRemoteControl(sessionId); - var tasks = GetControllers(session).Select(i => i.SendPlayCommand(session, command, cancellationToken)); - - return Task.WhenAll(tasks); + return session.SessionController.SendPlayCommand(command, cancellationToken); } /// @@ -506,9 +484,7 @@ namespace MediaBrowser.Server.Implementations.Session { var session = GetSessionForRemoteControl(sessionId); - var tasks = GetControllers(session).Select(i => i.SendBrowseCommand(session, command, cancellationToken)); - - return Task.WhenAll(tasks); + return session.SessionController.SendBrowseCommand(command, cancellationToken); } /// @@ -522,7 +498,25 @@ namespace MediaBrowser.Server.Implementations.Session { var session = GetSessionForRemoteControl(sessionId); - var tasks = GetControllers(session).Select(i => i.SendPlaystateCommand(session, command, cancellationToken)); + return session.SessionController.SendPlaystateCommand(command, cancellationToken); + } + + public Task SendRestartRequiredMessage(CancellationToken cancellationToken) + { + var sessions = Sessions.Where(i => i.IsActive && i.SessionController != null).ToList(); + + var tasks = sessions.Select(session => Task.Run(async () => + { + try + { + await session.SessionController.SendRestartRequiredMessage(cancellationToken).ConfigureAwait(false); + } + catch (Exception ex) + { + _logger.ErrorException("Error in SendRestartRequiredMessage.", ex); + } + + })); return Task.WhenAll(tasks); } diff --git a/MediaBrowser.Server.Implementations/Session/SessionWebSocketListener.cs b/MediaBrowser.Server.Implementations/Session/SessionWebSocketListener.cs index 0781e8228..e90dd8eb9 100644 --- a/MediaBrowser.Server.Implementations/Session/SessionWebSocketListener.cs +++ b/MediaBrowser.Server.Implementations/Session/SessionWebSocketListener.cs @@ -1,8 +1,8 @@ using MediaBrowser.Common.Net; +using MediaBrowser.Controller; using MediaBrowser.Controller.Dto; using MediaBrowser.Controller.Session; using MediaBrowser.Model.Logging; -using MediaBrowser.Model.Net; using System; using System.Linq; using System.Threading.Tasks; @@ -33,6 +33,7 @@ namespace MediaBrowser.Server.Implementations.Session /// The _dto service /// private readonly IDtoService _dtoService; + private readonly IServerApplicationHost _appHost; /// /// Initializes a new instance of the class. @@ -40,11 +41,12 @@ namespace MediaBrowser.Server.Implementations.Session /// The session manager. /// The log manager. /// The dto service. - public SessionWebSocketListener(ISessionManager sessionManager, ILogManager logManager, IDtoService dtoService) + public SessionWebSocketListener(ISessionManager sessionManager, ILogManager logManager, IDtoService dtoService, IServerApplicationHost appHost) { _sessionManager = sessionManager; _logger = logManager.GetLogger(GetType().Name); _dtoService = dtoService; + _appHost = appHost; } /// @@ -56,48 +58,11 @@ namespace MediaBrowser.Server.Implementations.Session { if (string.Equals(message.MessageType, "Identity", StringComparison.OrdinalIgnoreCase)) { - _logger.Debug("Received Identity message"); - - var vals = message.Data.Split('|'); - - var client = vals[0]; - var deviceId = vals[1]; - var version = vals[2]; - - var session = _sessionManager.Sessions - .FirstOrDefault(i => string.Equals(i.DeviceId, deviceId) && - string.Equals(i.Client, client) && - string.Equals(i.ApplicationVersion, version)); - - if (session != null) - { - var sockets = session.WebSockets.Where(i => i.State == WebSocketState.Open).ToList(); - sockets.Add(message.Connection); - - session.WebSockets = sockets; - } - else - { - _logger.Warn("Unable to determine session based on identity message: {0}", message.Data); - } + ProcessIdentityMessage(message); } else if (string.Equals(message.MessageType, "Context", StringComparison.OrdinalIgnoreCase)) { - var session = _sessionManager.Sessions.FirstOrDefault(i => i.WebSockets.Contains(message.Connection)); - - if (session != null) - { - var vals = message.Data.Split('|'); - - session.NowViewingItemType = vals[0]; - session.NowViewingItemId = vals[1]; - session.NowViewingItemName = vals[2]; - session.NowViewingContext = vals.Length > 3 ? vals[3] : null; - } - else - { - _logger.Warn("Unable to determine session based on context message: {0}", message.Data); - } + ProcessContextMessage(message); } else if (string.Equals(message.MessageType, "PlaybackStart", StringComparison.OrdinalIgnoreCase)) { @@ -105,79 +70,98 @@ namespace MediaBrowser.Server.Implementations.Session } else if (string.Equals(message.MessageType, "PlaybackProgress", StringComparison.OrdinalIgnoreCase)) { - var session = _sessionManager.Sessions.FirstOrDefault(i => i.WebSockets.Contains(message.Connection)); - - if (session != null && session.User != null) - { - var vals = message.Data.Split('|'); - - var item = _dtoService.GetItemByDtoId(vals[0]); - - long? positionTicks = null; - - if (vals.Length > 1) - { - long pos; - - if (long.TryParse(vals[1], out pos)) - { - positionTicks = pos; - } - } - - var isPaused = vals.Length > 2 && string.Equals(vals[2], "true", StringComparison.OrdinalIgnoreCase); - var isMuted = vals.Length > 3 && string.Equals(vals[3], "true", StringComparison.OrdinalIgnoreCase); - - var info = new PlaybackProgressInfo - { - Item = item, - PositionTicks = positionTicks, - IsMuted = isMuted, - IsPaused = isPaused, - SessionId = session.Id - }; - - _sessionManager.OnPlaybackProgress(info); - } + ReportPlaybackProgress(message); } else if (string.Equals(message.MessageType, "PlaybackStopped", StringComparison.OrdinalIgnoreCase)) { - _logger.Debug("Received PlaybackStopped message"); - - var session = _sessionManager.Sessions.FirstOrDefault(i => i.WebSockets.Contains(message.Connection)); - - if (session != null && session.User != null) - { - var vals = message.Data.Split('|'); - - var item = _dtoService.GetItemByDtoId(vals[0]); - - long? positionTicks = null; - - if (vals.Length > 1) - { - long pos; - - if (long.TryParse(vals[1], out pos)) - { - positionTicks = pos; - } - } - - var info = new PlaybackStopInfo - { - Item = item, - PositionTicks = positionTicks, - SessionId = session.Id - }; - - _sessionManager.OnPlaybackStopped(info); - } + ReportPlaybackStopped(message); } return _trueTaskResult; } + /// + /// Processes the identity message. + /// + /// The message. + private void ProcessIdentityMessage(WebSocketMessageInfo message) + { + _logger.Debug("Received Identity message"); + + var vals = message.Data.Split('|'); + + var client = vals[0]; + var deviceId = vals[1]; + var version = vals[2]; + + var session = _sessionManager.Sessions + .FirstOrDefault(i => string.Equals(i.DeviceId, deviceId) && + string.Equals(i.Client, client) && + string.Equals(i.ApplicationVersion, version)); + + if (session != null) + { + var controller = new WebSocketController(session, _appHost); + controller.Sockets.Add(message.Connection); + + session.SessionController = controller; + } + else + { + _logger.Warn("Unable to determine session based on identity message: {0}", message.Data); + } + } + + /// + /// Processes the context message. + /// + /// The message. + private void ProcessContextMessage(WebSocketMessageInfo message) + { + var session = GetSessionFromMessage(message); + + if (session != null) + { + var vals = message.Data.Split('|'); + + session.NowViewingItemType = vals[0]; + session.NowViewingItemId = vals[1]; + session.NowViewingItemName = vals[2]; + session.NowViewingContext = vals.Length > 3 ? vals[3] : null; + } + } + + /// + /// Gets the session from message. + /// + /// The message. + /// SessionInfo. + private SessionInfo GetSessionFromMessage(WebSocketMessageInfo message) + { + var result = _sessionManager.Sessions.FirstOrDefault(i => + { + var controller = i.SessionController as WebSocketController; + + if (controller != null) + { + if (controller.Sockets.Any(s => s.Id == message.Connection.Id)) + { + return true; + } + } + + return false; + + }); + + if (result == null) + { + _logger.Error("Unable to session based on web socket message"); + } + + return result; + } + /// /// Reports the playback start. /// @@ -185,9 +169,8 @@ namespace MediaBrowser.Server.Implementations.Session private void ReportPlaybackStart(WebSocketMessageInfo message) { _logger.Debug("Received PlaybackStart message"); - - var session = _sessionManager.Sessions - .FirstOrDefault(i => i.WebSockets.Contains(message.Connection)); + + var session = GetSessionFromMessage(message); if (session != null && session.User != null) { @@ -206,7 +189,7 @@ namespace MediaBrowser.Server.Implementations.Session { queueableMediaTypes = vals[2]; } - + var info = new PlaybackInfo { CanSeek = canSeek, @@ -218,5 +201,86 @@ namespace MediaBrowser.Server.Implementations.Session _sessionManager.OnPlaybackStart(info); } } + + /// + /// Reports the playback progress. + /// + /// The message. + private void ReportPlaybackProgress(WebSocketMessageInfo message) + { + var session = GetSessionFromMessage(message); + + if (session != null && session.User != null) + { + var vals = message.Data.Split('|'); + + var item = _dtoService.GetItemByDtoId(vals[0]); + + long? positionTicks = null; + + if (vals.Length > 1) + { + long pos; + + if (long.TryParse(vals[1], out pos)) + { + positionTicks = pos; + } + } + + var isPaused = vals.Length > 2 && string.Equals(vals[2], "true", StringComparison.OrdinalIgnoreCase); + var isMuted = vals.Length > 3 && string.Equals(vals[3], "true", StringComparison.OrdinalIgnoreCase); + + var info = new PlaybackProgressInfo + { + Item = item, + PositionTicks = positionTicks, + IsMuted = isMuted, + IsPaused = isPaused, + SessionId = session.Id + }; + + _sessionManager.OnPlaybackProgress(info); + } + } + + /// + /// Reports the playback stopped. + /// + /// The message. + private void ReportPlaybackStopped(WebSocketMessageInfo message) + { + _logger.Debug("Received PlaybackStopped message"); + + var session = GetSessionFromMessage(message); + + if (session != null && session.User != null) + { + var vals = message.Data.Split('|'); + + var item = _dtoService.GetItemByDtoId(vals[0]); + + long? positionTicks = null; + + if (vals.Length > 1) + { + long pos; + + if (long.TryParse(vals[1], out pos)) + { + positionTicks = pos; + } + } + + var info = new PlaybackStopInfo + { + Item = item, + PositionTicks = positionTicks, + SessionId = session.Id + }; + + _sessionManager.OnPlaybackStopped(info); + } + } } } diff --git a/MediaBrowser.Server.Implementations/Session/WebSocketController.cs b/MediaBrowser.Server.Implementations/Session/WebSocketController.cs index fb0bc9b7c..46c8f752d 100644 --- a/MediaBrowser.Server.Implementations/Session/WebSocketController.cs +++ b/MediaBrowser.Server.Implementations/Session/WebSocketController.cs @@ -1,8 +1,12 @@ 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; @@ -11,15 +15,39 @@ namespace MediaBrowser.Server.Implementations.Session { public class WebSocketController : ISessionController { - public bool Supports(SessionInfo session) + public SessionInfo Session { get; private set; } + public List Sockets { get; private set; } + + private readonly IServerApplicationHost _appHost; + + public WebSocketController(SessionInfo session, IServerApplicationHost appHost) { - return session.WebSockets.Any(i => i.State == WebSocketState.Open); + Session = session; + _appHost = appHost; + Sockets = new List(); } - private IWebSocketConnection GetSocket(SessionInfo session) + public bool SupportsMediaRemoteControl { - var socket = session.WebSockets.OrderByDescending(i => i.LastActivityDate).FirstOrDefault(i => i.State == WebSocketState.Open); + get + { + return Sockets.Any(i => i.State == WebSocketState.Open); + } + } + 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) { @@ -29,9 +57,9 @@ namespace MediaBrowser.Server.Implementations.Session return socket; } - public Task SendSystemCommand(SessionInfo session, SystemCommand command, CancellationToken cancellationToken) + public Task SendSystemCommand(SystemCommand command, CancellationToken cancellationToken) { - var socket = GetSocket(session); + var socket = GetActiveSocket(); return socket.SendAsync(new WebSocketMessage { @@ -41,9 +69,9 @@ namespace MediaBrowser.Server.Implementations.Session }, cancellationToken); } - public Task SendMessageCommand(SessionInfo session, MessageCommand command, CancellationToken cancellationToken) + public Task SendMessageCommand(MessageCommand command, CancellationToken cancellationToken) { - var socket = GetSocket(session); + var socket = GetActiveSocket(); return socket.SendAsync(new WebSocketMessage { @@ -53,9 +81,9 @@ namespace MediaBrowser.Server.Implementations.Session }, cancellationToken); } - public Task SendPlayCommand(SessionInfo session, PlayRequest command, CancellationToken cancellationToken) + public Task SendPlayCommand(PlayRequest command, CancellationToken cancellationToken) { - var socket = GetSocket(session); + var socket = GetActiveSocket(); return socket.SendAsync(new WebSocketMessage { @@ -65,9 +93,9 @@ namespace MediaBrowser.Server.Implementations.Session }, cancellationToken); } - public Task SendBrowseCommand(SessionInfo session, BrowseRequest command, CancellationToken cancellationToken) + public Task SendBrowseCommand(BrowseRequest command, CancellationToken cancellationToken) { - var socket = GetSocket(session); + var socket = GetActiveSocket(); return socket.SendAsync(new WebSocketMessage { @@ -77,9 +105,9 @@ namespace MediaBrowser.Server.Implementations.Session }, cancellationToken); } - public Task SendPlaystateCommand(SessionInfo session, PlaystateRequest command, CancellationToken cancellationToken) + public Task SendPlaystateCommand(PlaystateRequest command, CancellationToken cancellationToken) { - var socket = GetSocket(session); + var socket = GetActiveSocket(); return socket.SendAsync(new WebSocketMessage { @@ -88,5 +116,34 @@ namespace MediaBrowser.Server.Implementations.Session }, cancellationToken); } + + public Task SendLibraryUpdateInfo(LibraryUpdateInfo info, CancellationToken cancellationToken) + { + var socket = GetActiveSocket(); + + return socket.SendAsync(new WebSocketMessage + { + MessageType = "Playstate", + Data = info + + }, cancellationToken); + } + + /// + /// Sends the restart required message. + /// + /// The cancellation token. + /// Task. + public Task SendRestartRequiredMessage(CancellationToken cancellationToken) + { + var socket = GetActiveSocket(); + + return socket.SendAsync(new WebSocketMessage + { + MessageType = "RestartRequired", + Data = _appHost.GetSystemInfo() + + }, cancellationToken); + } } } diff --git a/MediaBrowser.ServerApplication/ApplicationHost.cs b/MediaBrowser.ServerApplication/ApplicationHost.cs index c9d079fc7..a10b7c15b 100644 --- a/MediaBrowser.ServerApplication/ApplicationHost.cs +++ b/MediaBrowser.ServerApplication/ApplicationHost.cs @@ -427,8 +427,6 @@ namespace MediaBrowser.ServerApplication ProviderManager.AddParts(GetExports()); - SessionManager.AddParts(GetExports()); - ImageProcessor.AddParts(GetExports()); LiveTvManager.AddParts(GetExports()); diff --git a/MediaBrowser.ServerApplication/Native/BrowserLauncher.cs b/MediaBrowser.ServerApplication/Native/BrowserLauncher.cs index 8b0beab48..43a698434 100644 --- a/MediaBrowser.ServerApplication/Native/BrowserLauncher.cs +++ b/MediaBrowser.ServerApplication/Native/BrowserLauncher.cs @@ -46,7 +46,7 @@ namespace MediaBrowser.ServerApplication.Native /// The logger. public static void OpenCommunity(ILogger logger) { - OpenUrl("http://community.mediabrowser.tv/", logger); + OpenUrl("http://mediabrowser3.com/community", logger); } /// diff --git a/Nuget/MediaBrowser.Common.Internal.nuspec b/Nuget/MediaBrowser.Common.Internal.nuspec index f9ccca41e..18187392a 100644 --- a/Nuget/MediaBrowser.Common.Internal.nuspec +++ b/Nuget/MediaBrowser.Common.Internal.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Common.Internal - 3.0.215 + 3.0.216 MediaBrowser.Common.Internal Luke ebr,Luke,scottisafool @@ -12,7 +12,7 @@ Contains common components shared by Media Browser Theater and Media Browser Server. Not intended for plugin developer consumption. Copyright © Media Browser 2013 - + diff --git a/Nuget/MediaBrowser.Common.nuspec b/Nuget/MediaBrowser.Common.nuspec index 2045689ae..a9cc361a9 100644 --- a/Nuget/MediaBrowser.Common.nuspec +++ b/Nuget/MediaBrowser.Common.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Common - 3.0.215 + 3.0.216 MediaBrowser.Common Media Browser Team ebr,Luke,scottisafool diff --git a/Nuget/MediaBrowser.Server.Core.nuspec b/Nuget/MediaBrowser.Server.Core.nuspec index 4d306b695..56e9222d4 100644 --- a/Nuget/MediaBrowser.Server.Core.nuspec +++ b/Nuget/MediaBrowser.Server.Core.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Server.Core - 3.0.215 + 3.0.216 Media Browser.Server.Core Media Browser Team ebr,Luke,scottisafool @@ -12,7 +12,7 @@ Contains core components required to build plugins for Media Browser Server. Copyright © Media Browser 2013 - +