WebsocketService.cs 2.7 KB

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