WebSocketManager.cs 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. #pragma warning disable CS1591
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Net.WebSockets;
  6. using System.Threading.Tasks;
  7. using MediaBrowser.Controller.Net;
  8. using Microsoft.AspNetCore.Http;
  9. using Microsoft.Extensions.Logging;
  10. namespace Emby.Server.Implementations.HttpServer
  11. {
  12. public class WebSocketManager : IWebSocketManager
  13. {
  14. private readonly IWebSocketListener[] _webSocketListeners;
  15. private readonly IAuthService _authService;
  16. private readonly ILogger<WebSocketManager> _logger;
  17. private readonly ILoggerFactory _loggerFactory;
  18. public WebSocketManager(
  19. IAuthService authService,
  20. IEnumerable<IWebSocketListener> webSocketListeners,
  21. ILogger<WebSocketManager> logger,
  22. ILoggerFactory loggerFactory)
  23. {
  24. _webSocketListeners = webSocketListeners.ToArray();
  25. _authService = authService;
  26. _logger = logger;
  27. _loggerFactory = loggerFactory;
  28. }
  29. /// <inheritdoc />
  30. public async Task WebSocketRequestHandler(HttpContext context)
  31. {
  32. _ = _authService.Authenticate(context.Request);
  33. try
  34. {
  35. _logger.LogInformation("WS {IP} request", context.Connection.RemoteIpAddress);
  36. WebSocket webSocket = await context.WebSockets.AcceptWebSocketAsync().ConfigureAwait(false);
  37. using var connection = new WebSocketConnection(
  38. _loggerFactory.CreateLogger<WebSocketConnection>(),
  39. webSocket,
  40. context.Connection.RemoteIpAddress,
  41. context.Request.Query)
  42. {
  43. OnReceive = ProcessWebSocketMessageReceived
  44. };
  45. var tasks = new Task[_webSocketListeners.Length];
  46. for (var i = 0; i < _webSocketListeners.Length; ++i)
  47. {
  48. tasks[i] = _webSocketListeners[i].ProcessWebSocketConnectedAsync(connection);
  49. }
  50. await Task.WhenAll(tasks).ConfigureAwait(false);
  51. await connection.ProcessAsync().ConfigureAwait(false);
  52. _logger.LogInformation("WS {IP} closed", context.Connection.RemoteIpAddress);
  53. }
  54. catch (Exception ex) // Otherwise ASP.Net will ignore the exception
  55. {
  56. _logger.LogError(ex, "WS {IP} WebSocketRequestHandler error", context.Connection.RemoteIpAddress);
  57. if (!context.Response.HasStarted)
  58. {
  59. context.Response.StatusCode = 500;
  60. }
  61. }
  62. }
  63. /// <summary>
  64. /// Processes the web socket message received.
  65. /// </summary>
  66. /// <param name="result">The result.</param>
  67. private Task ProcessWebSocketMessageReceived(WebSocketMessageInfo result)
  68. {
  69. var tasks = new Task[_webSocketListeners.Length];
  70. for (var i = 0; i < _webSocketListeners.Length; ++i)
  71. {
  72. tasks[i] = _webSocketListeners[i].ProcessMessageAsync(result);
  73. }
  74. return Task.WhenAll(tasks);
  75. }
  76. }
  77. }