WebsocketService.cs 2.7 KB

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