WebsocketService.cs 2.5 KB

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