123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286 |
- using MediaBrowser.Common.Net;
- using MediaBrowser.Controller;
- using MediaBrowser.Controller.Dto;
- using MediaBrowser.Controller.Session;
- using MediaBrowser.Model.Logging;
- using System;
- using System.Linq;
- using System.Threading.Tasks;
- namespace MediaBrowser.Server.Implementations.Session
- {
- /// <summary>
- /// Class SessionWebSocketListener
- /// </summary>
- public class SessionWebSocketListener : IWebSocketListener
- {
- /// <summary>
- /// The _true task result
- /// </summary>
- private readonly Task _trueTaskResult = Task.FromResult(true);
- /// <summary>
- /// The _session manager
- /// </summary>
- private readonly ISessionManager _sessionManager;
- /// <summary>
- /// The _logger
- /// </summary>
- private readonly ILogger _logger;
- /// <summary>
- /// The _dto service
- /// </summary>
- private readonly IDtoService _dtoService;
- private readonly IServerApplicationHost _appHost;
- /// <summary>
- /// Initializes a new instance of the <see cref="SessionWebSocketListener" /> class.
- /// </summary>
- /// <param name="sessionManager">The session manager.</param>
- /// <param name="logManager">The log manager.</param>
- /// <param name="dtoService">The dto service.</param>
- public SessionWebSocketListener(ISessionManager sessionManager, ILogManager logManager, IDtoService dtoService, IServerApplicationHost appHost)
- {
- _sessionManager = sessionManager;
- _logger = logManager.GetLogger(GetType().Name);
- _dtoService = dtoService;
- _appHost = appHost;
- }
- /// <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;
- }
- /// <summary>
- /// Processes the identity message.
- /// </summary>
- /// <param name="message">The message.</param>
- 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);
- }
- }
- /// <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;
- }
- }
- /// <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 session based on web socket message");
- }
- return result;
- }
- /// <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);
- }
- }
- /// <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);
- }
- }
- /// <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);
- }
- }
- }
- }
|