WebsocketService.cs 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. using Microsoft.AspNetCore.Builder;
  2. using Microsoft.AspNetCore.Http;
  3. using Microsoft.Extensions.DependencyInjection;
  4. using Microsoft.Extensions.Primitives;
  5. using System.Net.WebSockets;
  6. using System.Text;
  7. namespace EVCB_OCPP.WSServer.Service.WsService;
  8. public static class AppExtention
  9. {
  10. public static void MapWsService(this WebApplication webApplication)
  11. {
  12. var protocals = new List<string>() { "", "ocpp1.6", "ocpp2.0" };
  13. webApplication.UseWebSockets(new WebSocketOptions()
  14. {
  15. KeepAliveInterval = TimeSpan.FromSeconds(10)
  16. });
  17. webApplication.Use(async (context, next) =>
  18. {
  19. if (!context.WebSockets.IsWebSocketRequest)
  20. {
  21. await next(context);
  22. return;
  23. }
  24. var matched = context.WebSockets.WebSocketRequestedProtocols.Intersect(protocals);
  25. if (matched is null || !matched.Any())
  26. {
  27. await context.Response.WriteAsync("Protocol not matched");
  28. return;
  29. }
  30. using WebSocket webSocket = await context.WebSockets.AcceptWebSocketAsync(matched.Last());
  31. var servcie = context.RequestServices.GetService<WebsocketService<WsClientData>>();
  32. await servcie.AddWebSocket(webSocket, context);
  33. return;
  34. });
  35. }
  36. }
  37. public class WebsocketService<T> where T : WsSession
  38. {
  39. public WebsocketService() { }
  40. public Func<T, Task<bool>> ValidateHandshake;
  41. public event EventHandler<T> NewSessionConnected;
  42. public async Task AddWebSocket(WebSocket webSocket, HttpContext context)
  43. {
  44. T data = Activator.CreateInstance<T>();
  45. data.ClientWebSocket = webSocket;
  46. data.Path = context?.Request?.Path;
  47. data.UriScheme = context?.Request?.Scheme;
  48. data.AuthHeader = context?.Request?.Headers?.Authorization;
  49. data.SessionID = context.TraceIdentifier;
  50. data.Endpoint = null;
  51. data.Origin = context.Request.Headers.Origin;
  52. var validated = ValidateHandshake == null ? false : await ValidateHandshake(data);
  53. if (!validated)
  54. {
  55. return;
  56. }
  57. NewSessionConnected?.Invoke(this, data);
  58. await data.EndConnSemaphore.WaitAsync();
  59. return;
  60. }
  61. }
  62. public enum CloseReason
  63. {
  64. ClientClosing,
  65. ServerShutdown
  66. }