/// <summary>
        /// Processes the message.
        /// </summary>
        /// <param name="message">The message.</param>
        /// <returns>Task.</returns>
        public Task ProcessMessage(WebSocketMessageInfo message)
        {
            if (string.Equals(message.MessageType, "Identity", StringComparison.OrdinalIgnoreCase))
            {
                ProcessIdentityMessage(message);
            }
            else if (string.Equals(message.MessageType, "Context", StringComparison.OrdinalIgnoreCase))
            {
                ProcessContextMessage(message);
            }
            else if (string.Equals(message.MessageType, "PlaybackStart", StringComparison.OrdinalIgnoreCase))
            {
                ReportPlaybackStart(message);
            }
            else if (string.Equals(message.MessageType, "PlaybackProgress", StringComparison.OrdinalIgnoreCase))
            {
                ReportPlaybackProgress(message);
            }
            else if (string.Equals(message.MessageType, "PlaybackStopped", StringComparison.OrdinalIgnoreCase))
            {
                ReportPlaybackStopped(message);
            }

            return _trueTaskResult;
        }
        private void ReportPlaybackStopped(WebSocketMessageInfo message)
        {
            _logger.Debug("Received ReportPlaybackStopped message");

            var session = GetSessionFromMessage(message);

            if (session != null && session.UserId.HasValue)
            {
                var info = _json.DeserializeFromString<PlaybackStopInfo>(message.Data);

                info.SessionId = session.Id;

                _sessionManager.OnPlaybackStopped(info);
            }
        }
        /// <summary>
        /// Reports the playback progress.
        /// </summary>
        /// <param name="message">The message.</param>
        private void OnPlaybackProgress(WebSocketMessageInfo message)
        {
            var session = GetSessionFromMessage(message);

            if (session != null && session.UserId.HasValue)
            {
                var vals = message.Data.Split('|');

                var itemId = 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
                {
                    ItemId = itemId,
                    PositionTicks = positionTicks,
                    IsMuted = isMuted,
                    IsPaused = isPaused,
                    SessionId = session.Id
                };

                if (vals.Length > 4)
                {
                    info.MediaSourceId = vals[4];
                }

                if (vals.Length > 5 && !string.IsNullOrWhiteSpace(vals[5]))
                {
                    info.VolumeLevel = int.Parse(vals[5], _usCulture);
                }

                if (vals.Length > 5 && !string.IsNullOrWhiteSpace(vals[6]))
                {
                    info.AudioStreamIndex = int.Parse(vals[6], _usCulture);
                }

                if (vals.Length > 7 && !string.IsNullOrWhiteSpace(vals[7]))
                {
                    info.SubtitleStreamIndex = int.Parse(vals[7], _usCulture);
                }

                _sessionManager.OnPlaybackProgress(info);
            }
        }
        /// <summary>
        /// Reports the playback start.
        /// </summary>
        /// <param name="message">The message.</param>
        private void OnPlaybackStart(WebSocketMessageInfo message)
        {
            _logger.Debug("Received PlaybackStart message");

            var session = GetSessionFromMessage(message);

            if (session != null && session.UserId.HasValue)
            {
                var vals = message.Data.Split('|');

                var itemId = vals[0];

                var queueableMediaTypes = string.Empty;
                var canSeek = true;

                if (vals.Length > 1)
                {
                    canSeek = string.Equals(vals[1], "true", StringComparison.OrdinalIgnoreCase);
                }
                if (vals.Length > 2)
                {
                    queueableMediaTypes = vals[2];
                }

                var info = new PlaybackStartInfo
                {
                    CanSeek = canSeek,
                    ItemId = itemId,
                    SessionId = session.Id,
                    QueueableMediaTypes = queueableMediaTypes.Split(',').ToList()
                };

                if (vals.Length > 3)
                {
                    info.MediaSourceId = vals[3];
                }

                if (vals.Length > 4 && !string.IsNullOrWhiteSpace(vals[4]))
                {
                    info.AudioStreamIndex = int.Parse(vals[4], _usCulture);
                }

                if (vals.Length > 5 && !string.IsNullOrWhiteSpace(vals[5]))
                {
                    info.SubtitleStreamIndex = int.Parse(vals[5], _usCulture);
                }

                _sessionManager.OnPlaybackStart(info);
            }
        }
        /// <summary>
        /// Gets the session from message.
        /// </summary>
        /// <param name="message">The message.</param>
        /// <returns>SessionInfo.</returns>
        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 find session based on web socket message");
            }

            return result;
        }
        /// <summary>
        /// Processes the context message.
        /// </summary>
        /// <param name="message">The message.</param>
        private void ProcessContextMessage(WebSocketMessageInfo message)
        {
            var session = GetSessionFromMessage(message);

            if (session != null)
            {
                var vals = message.Data.Split('|');

                _sessionManager.ReportNowViewingItem(session.Id, vals[1]);
            }
        }
        /// <summary>
        /// Reports the playback progress.
        /// </summary>
        /// <param name="message">The message.</param>
        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);
            }
        }
Esempio n. 8
0
 /// <summary>
 /// Processes the message.
 /// </summary>
 /// <param name="message">The message.</param>
 /// <returns>Task.</returns>
 public Task ProcessMessageAsync(WebSocketMessageInfo message)
 => Task.CompletedTask;
        /// <summary>
        /// Processes the message.
        /// </summary>
        /// <param name="message">The message.</param>
        /// <returns>Task.</returns>
        public Task ProcessMessage(WebSocketMessageInfo message)
        {
            if (string.Equals(message.MessageType, "Identity", StringComparison.OrdinalIgnoreCase))
            {
                var vals = message.Data.Split('|');

                var client = vals[0];
                var deviceId = vals[1];

                var session = _sessionManager.Sessions.FirstOrDefault(i => string.Equals(i.DeviceId, deviceId) && string.Equals(i.Client, client));

                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);
                }
            }
            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);
                }
            }
            else if (string.Equals(message.MessageType, "PlaybackStart", StringComparison.OrdinalIgnoreCase))
            {
                var session = _sessionManager.Sessions.FirstOrDefault(i => i.WebSockets.Contains(message.Connection));

                if (session != null && session.User != null)
                {
                    var item = DtoBuilder.GetItemByClientId(message.Data, _userManager, _libraryManager);

                    _sessionManager.OnPlaybackStart(_userManager.GetUserById(session.User.Id), item, session.Client, session.DeviceId, session.DeviceName);
                }
            }
            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 = DtoBuilder.GetItemByClientId(vals[0], _userManager, _libraryManager);

                    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);

                    _sessionManager.OnPlaybackProgress(_userManager.GetUserById(session.User.Id), item, positionTicks, isPaused, session.Client, session.DeviceId, session.DeviceName);
                }
            }
            else if (string.Equals(message.MessageType, "PlaybackStopped", 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 = DtoBuilder.GetItemByClientId(vals[0], _userManager, _libraryManager);

                    long? positionTicks = null;

                    if (vals.Length > 1)
                    {
                        long pos;

                        if (long.TryParse(vals[1], out pos))
                        {
                            positionTicks = pos;
                        }
                    }

                    _sessionManager.OnPlaybackStopped(_userManager.GetUserById(session.User.Id), item, positionTicks, session.Client, session.DeviceId, session.DeviceName);
                }
            }

            return _trueTaskResult;
        }
        /// <summary>
        /// Processes the context message.
        /// </summary>
        /// <param name="message">The message.</param>
        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;
            }
        }
Esempio n. 11
0
        /// <summary>
        /// Processes the message.
        /// </summary>
        /// <param name="message">The message.</param>
        /// <returns>Task.</returns>
        public Task ProcessMessage(WebSocketMessageInfo message)
        {
            if (string.Equals(message.MessageType, "Identity", StringComparison.OrdinalIgnoreCase))
            {
                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);
                }
            }
            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);
                }
            }
            else if (string.Equals(message.MessageType, "PlaybackStart", StringComparison.OrdinalIgnoreCase))
            {
                var session = _sessionManager.Sessions.FirstOrDefault(i => i.WebSockets.Contains(message.Connection));

                if (session != null && session.User != null)
                {
                    var item = DtoBuilder.GetItemByClientId(message.Data, _userManager, _libraryManager);

                    _sessionManager.OnPlaybackStart(item, session.Id);
                }
            }
            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 = DtoBuilder.GetItemByClientId(vals[0], _userManager, _libraryManager);

                    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);

                    _sessionManager.OnPlaybackProgress(item, positionTicks, isPaused, session.Id);
                }
            }
            else if (string.Equals(message.MessageType, "PlaybackStopped", 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 = DtoBuilder.GetItemByClientId(vals[0], _userManager, _libraryManager);

                    long?positionTicks = null;

                    if (vals.Length > 1)
                    {
                        long pos;

                        if (long.TryParse(vals[1], out pos))
                        {
                            positionTicks = pos;
                        }
                    }

                    _sessionManager.OnPlaybackStopped(item, positionTicks, session.Id);
                }
            }

            return(_trueTaskResult);
        }
        /// <summary>
        /// Processes the identity message.
        /// </summary>
        /// <param name="message">The message.</param>
        private async void ProcessIdentityMessage(WebSocketMessageInfo message)
        {
            _logger.Debug("Received Identity message: " + message.Data);

            var vals = message.Data.Split('|');

            var client = vals[0];
            var deviceId = vals[1];
            var version = vals[2];
            var deviceName = vals.Length > 3 ? vals[3] : string.Empty;

            var session = _sessionManager.Sessions
                .FirstOrDefault(i => string.Equals(i.DeviceId, deviceId) &&
                    string.Equals(i.Client, client) &&
                    string.Equals(i.ApplicationVersion, version));

            if (session == null && !string.IsNullOrEmpty(deviceName))
            {
                _logger.Debug("Logging session activity");

                await _sessionManager.LogSessionActivity(client, version, deviceId, deviceName, null).ConfigureAwait(false);

                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);
            }
        }
        /// <summary>
        /// Reports the playback stopped.
        /// </summary>
        /// <param name="message">The message.</param>
        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);
            }
        }
        /// <summary>
        /// Reports the playback stopped.
        /// </summary>
        /// <param name="message">The message.</param>
        private void OnPlaybackStopped(WebSocketMessageInfo message)
        {
            _logger.Debug("Received PlaybackStopped message");

            var session = GetSessionFromMessage(message);

            if (session != null && session.UserId.HasValue)
            {
                var vals = message.Data.Split('|');

                var itemId = vals[0];

                long? positionTicks = null;

                if (vals.Length > 1)
                {
                    long pos;

                    if (long.TryParse(vals[1], out pos))
                    {
                        positionTicks = pos;
                    }
                }

                var info = new PlaybackStopInfo
                {
                    ItemId = itemId,
                    PositionTicks = positionTicks,
                    SessionId = session.Id
                };

                if (vals.Length > 2)
                {
                    info.MediaSourceId = vals[2];
                }

                _sessionManager.OnPlaybackStopped(info);
            }
        }
Esempio n. 15
0
 /// <summary>
 /// Processes the message.
 /// </summary>
 /// <param name="message">The message.</param>
 /// <returns>Task.</returns>
 public Task ProcessMessage(WebSocketMessageInfo message)
 {
     return(Task.CompletedTask);
 }
        /// <summary>
        /// Processes the identity message.
        /// </summary>
        /// <param name="message">The message.</param>
        private async void ProcessIdentityMessage(WebSocketMessageInfo message)
        {
            _logger.Debug("Received Identity message: " + message.Data);

            var vals = message.Data.Split('|');

            if (vals.Length < 3)
            {
                _logger.Error("Client sent invalid identity message.");
                return;
            }

            var client = vals[0];
            var deviceId = vals[1];
            var version = vals[2];
            var deviceName = vals.Length > 3 ? vals[3] : string.Empty;

            var session = _sessionManager.GetSession(deviceId, client, version);

            if (session == null && !string.IsNullOrEmpty(deviceName))
            {
                _logger.Debug("Logging session activity");

                session = await _sessionManager.LogSessionActivity(client, version, deviceId, deviceName, message.Connection.RemoteEndPoint, null).ConfigureAwait(false);
            }

            if (session != null)
            {
                var controller = session.SessionController as WebSocketController;

                if (controller == null)
                {
                    controller = new WebSocketController(session, _logger, _sessionManager);
                }

                controller.AddWebSocket(message.Connection);

                session.SessionController = controller;
            }
            else
            {
                _logger.Warn("Unable to determine session based on identity message: {0}", message.Data);
            }
        }
Esempio n. 17
0
        /// <summary>
        /// Processes the context message.
        /// </summary>
        /// <param name="message">The message.</param>
        private void ProcessContextMessage(WebSocketMessageInfo message)
        {
            var session = GetSessionFromMessage(message);

            if (session != null)
            {
                var vals = message.Data.Split('|');

                var itemId = vals[1];

                if (!string.IsNullOrWhiteSpace(itemId))
                {
                    _sessionManager.ReportNowViewingItem(session.Id, itemId);
                }
            }
        }
Esempio n. 18
0
        private async Task ProcessInternal(PipeReader reader)
        {
            ReadResult result = await reader.ReadAsync().ConfigureAwait(false);

            ReadOnlySequence <byte> buffer = result.Buffer;

            if (OnReceive == null)
            {
                // Tell the PipeReader how much of the buffer we have consumed
                reader.AdvanceTo(buffer.End);
                return;
            }

            WebSocketMessage <object> stub;

            try
            {
                if (buffer.IsSingleSegment)
                {
                    stub = JsonSerializer.Deserialize <WebSocketMessage <object> >(buffer.FirstSpan, _jsonOptions);
                }
                else
                {
                    var buf = ArrayPool <byte> .Shared.Rent(Convert.ToInt32(buffer.Length));

                    try
                    {
                        buffer.CopyTo(buf);
                        stub = JsonSerializer.Deserialize <WebSocketMessage <object> >(buf, _jsonOptions);
                    }
                    finally
                    {
                        ArrayPool <byte> .Shared.Return(buf);
                    }
                }
            }
            catch (JsonException ex)
            {
                // Tell the PipeReader how much of the buffer we have consumed
                reader.AdvanceTo(buffer.End);
                _logger.LogError(ex, "Error processing web socket message");
                return;
            }

            // Tell the PipeReader how much of the buffer we have consumed
            reader.AdvanceTo(buffer.End);

            _logger.LogDebug("WS {IP} received message: {@Message}", RemoteEndPoint, stub);

            var info = new WebSocketMessageInfo
            {
                MessageType = stub.MessageType,
                Data        = stub.Data?.ToString(), // Data can be null
                Connection  = this
            };

            if (info.MessageType.Equals("KeepAlive", StringComparison.Ordinal))
            {
                await SendKeepAliveResponse();
            }
            else
            {
                await OnReceive(info).ConfigureAwait(false);
            }
        }
        /// <summary>
        /// Reports the playback start.
        /// </summary>
        /// <param name="message">The message.</param>
        private void ReportPlaybackStart(WebSocketMessageInfo message)
        {
            _logger.Debug("Received PlaybackStart message");

            var session = GetSessionFromMessage(message);

            if (session != null && session.User != null)
            {
                var vals = message.Data.Split('|');

                var item = _dtoService.GetItemByDtoId(vals[0]);

                var queueableMediaTypes = string.Empty;
                var canSeek = true;

                if (vals.Length > 1)
                {
                    canSeek = string.Equals(vals[1], "true", StringComparison.OrdinalIgnoreCase);
                }
                if (vals.Length > 2)
                {
                    queueableMediaTypes = vals[2];
                }

                var info = new PlaybackInfo
                {
                    CanSeek = canSeek,
                    Item = item,
                    SessionId = session.Id,
                    QueueableMediaTypes = queueableMediaTypes.Split(',').ToList()
                };

                _sessionManager.OnPlaybackStart(info);
            }
        }