WebSocketController.cs 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Net.WebSockets;
  5. using System.Threading;
  6. using System.Threading.Tasks;
  7. using MediaBrowser.Controller.Net;
  8. using MediaBrowser.Controller.Session;
  9. using MediaBrowser.Model.Net;
  10. using Microsoft.Extensions.Logging;
  11. namespace Emby.Server.Implementations.Session
  12. {
  13. public sealed class WebSocketController : ISessionController, IDisposable
  14. {
  15. private readonly ILogger _logger;
  16. private readonly ISessionManager _sessionManager;
  17. private readonly SessionInfo _session;
  18. private List<IWebSocketConnection> _sockets;
  19. private bool _disposed = false;
  20. public WebSocketController(
  21. ILogger<WebSocketController> logger,
  22. SessionInfo session,
  23. ISessionManager sessionManager)
  24. {
  25. _logger = logger;
  26. _session = session;
  27. _sessionManager = sessionManager;
  28. _sockets = new List<IWebSocketConnection>();
  29. }
  30. private bool HasOpenSockets => GetActiveSockets().Any();
  31. /// <inheritdoc />
  32. public bool SupportsMediaControl => HasOpenSockets;
  33. /// <inheritdoc />
  34. public bool IsSessionActive => HasOpenSockets;
  35. private IEnumerable<IWebSocketConnection> GetActiveSockets()
  36. => _sockets.Where(i => i.State == WebSocketState.Open);
  37. /// <inheritdoc />
  38. public void AddWebSocket(IWebSocketConnection connection)
  39. {
  40. _logger.LogDebug("Adding websocket to session {Session}", _session.Id);
  41. _sockets.Add(connection);
  42. connection.Closed += OnConnectionClosed;
  43. }
  44. private void OnConnectionClosed(object sender, EventArgs e)
  45. {
  46. var connection = (IWebSocketConnection)sender;
  47. _logger.LogDebug("Removing websocket from session {Session}", _session.Id);
  48. _sockets.Remove(connection);
  49. connection.Closed -= OnConnectionClosed;
  50. _sessionManager.CloseIfNeeded(_session);
  51. }
  52. /// <inheritdoc />
  53. public Task SendMessage<T>(
  54. string name,
  55. Guid messageId,
  56. T data,
  57. CancellationToken cancellationToken)
  58. {
  59. var socket = GetActiveSockets()
  60. .OrderByDescending(i => i.LastActivityDate)
  61. .FirstOrDefault();
  62. if (socket == null)
  63. {
  64. return Task.CompletedTask;
  65. }
  66. return socket.SendAsync(new WebSocketMessage<T>
  67. {
  68. Data = data,
  69. MessageType = name,
  70. MessageId = messageId
  71. }, cancellationToken);
  72. }
  73. /// <inheritdoc />
  74. public void Dispose()
  75. {
  76. if (_disposed)
  77. {
  78. return;
  79. }
  80. foreach (var socket in _sockets)
  81. {
  82. socket.Closed -= OnConnectionClosed;
  83. }
  84. _disposed = true;
  85. }
  86. }
  87. }