WebsocketService.cs 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. using Microsoft.AspNetCore.Http;
  2. using Microsoft.Extensions.DependencyInjection;
  3. using System.Net;
  4. using System.Net.Http;
  5. using System.Net.WebSockets;
  6. namespace EVCB_OCPP.WSServer.Service.WsService;
  7. public class WebsocketService<T> where T : WsSession
  8. {
  9. public WebsocketService(IServiceProvider serviceProvider)
  10. {
  11. this.serviceProvider = serviceProvider;
  12. }
  13. private readonly IServiceProvider serviceProvider;
  14. public event EventHandler<T> NewSessionConnected;
  15. public async Task AcceptWebSocket(HttpContext context)
  16. {
  17. if (!context.WebSockets.IsWebSocketRequest)
  18. {
  19. return;
  20. }
  21. var portocol = await ValidateSupportedPortocol(context);
  22. if (string.IsNullOrEmpty(portocol))
  23. {
  24. return;
  25. }
  26. T data = GetSession(context);
  27. if (!await ValidateHandshake(context, data))
  28. {
  29. return;
  30. }
  31. using WebSocket webSocket = await context.WebSockets.AcceptWebSocketAsync(portocol);
  32. await AddWebSocket(webSocket, data);
  33. }
  34. internal virtual ValueTask<bool> ValidateHandshake(HttpContext context, T data)
  35. {
  36. return ValueTask.FromResult(true);
  37. }
  38. internal virtual ValueTask<string> ValidateSupportedPortocol(HttpContext context)
  39. {
  40. return ValueTask.FromResult(string.Empty);
  41. }
  42. private async Task AddWebSocket(WebSocket webSocket, T data)
  43. {
  44. data.ClientWebSocket = webSocket;
  45. NewSessionConnected?.Invoke(this, data);
  46. await data.EndConnSemaphore.WaitAsync();
  47. return;
  48. }
  49. private T GetSession(HttpContext context)
  50. {
  51. T data = serviceProvider.GetRequiredService<T>();
  52. data.Path = context?.Request?.Path;
  53. data.SessionID = context.TraceIdentifier;
  54. data.UriScheme = GetScheme(context);
  55. try
  56. {
  57. var ipaddress = context.Connection.RemoteIpAddress;
  58. var port = context.Connection.RemotePort;
  59. data.Endpoint = new IPEndPoint(ipaddress, port);
  60. }
  61. catch
  62. {
  63. data.Endpoint = null;
  64. }
  65. return data;
  66. }
  67. private string GetScheme(HttpContext context)
  68. {
  69. string toReturn = string.Empty;
  70. if (context.Request.Headers.ContainsKey("x-original-host"))
  71. {
  72. toReturn = new Uri(context.Request.Headers["x-original-host"]).Scheme;
  73. return toReturn;
  74. }
  75. var origin = context.Request.Headers.Origin.FirstOrDefault();
  76. try
  77. {
  78. toReturn = new Uri(origin).Scheme;
  79. return toReturn;
  80. }
  81. catch
  82. {
  83. }
  84. return toReturn;
  85. }
  86. }