OcppWebsocketService.cs 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. using Microsoft.AspNetCore.Builder;
  2. using Microsoft.AspNetCore.Http;
  3. using Microsoft.Extensions.DependencyInjection;
  4. using Microsoft.Extensions.Logging;
  5. using Newtonsoft.Json;
  6. using System.Net.WebSockets;
  7. namespace EVCB_OCPP.WSServer.Service.WsService;
  8. public static class AppExtention
  9. {
  10. public static void AddOcppWsServer(this IServiceCollection services)
  11. {
  12. services.AddTransient<WsClientData>();
  13. services.AddSingleton<OcppWebsocketService>();
  14. }
  15. public static void MapOcppWsService(this WebApplication webApplication)
  16. {
  17. webApplication.UseWebSockets(new WebSocketOptions()
  18. {
  19. KeepAliveInterval = TimeSpan.FromSeconds(10)
  20. });
  21. webApplication.Use(async (context, next) =>
  22. {
  23. if (!context.WebSockets.IsWebSocketRequest)
  24. {
  25. await next(context);
  26. return;
  27. }
  28. var servcie = context.RequestServices.GetService<OcppWebsocketService>();
  29. await servcie.AcceptWebSocket(context);
  30. return;
  31. });
  32. }
  33. }
  34. public class OcppWebsocketService : WebsocketService<WsClientData>
  35. {
  36. public static List<string> protocals = new List<string>() { "", "ocpp1.6", "ocpp2.0.1" };
  37. private readonly ILogger<OcppWebsocketService> logger;
  38. public OcppWebsocketService(
  39. IServiceProvider serviceProvider,
  40. ILogger<OcppWebsocketService> logger
  41. ) : base(serviceProvider)
  42. {
  43. this.logger = logger;
  44. }
  45. internal override async ValueTask<string> AcceptWebSocketHandler(HttpContext context)
  46. {
  47. logger.LogInformation("{function}:{Path}/{SubProtocol}", nameof(AcceptWebSocketHandler), context.Request.Path, context.WebSockets.WebSocketRequestedProtocols);
  48. var protocol = GetSupportedPortocol(context.WebSockets.WebSocketRequestedProtocols, protocals);
  49. if (string.IsNullOrEmpty(protocol))
  50. {
  51. logger.LogInformation("{function}:{Path} Protocol Not Supported, Disconnecting", nameof(AcceptWebSocketHandler), context.Request.Path);
  52. using WebSocket toRejectwebSocket = await context.WebSockets.AcceptWebSocketAsync();
  53. await toRejectwebSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, null, default);
  54. return string.Empty;
  55. }
  56. return protocol;
  57. }
  58. private static string GetSupportedPortocol(IList<string> clientProtocols, IList<string> supportedProtocols)
  59. {
  60. int supportedProtocolIndex = supportedProtocols.Count - 1;
  61. for (; supportedProtocolIndex >= 0; supportedProtocolIndex--)
  62. {
  63. var testProtocol = supportedProtocols[supportedProtocolIndex];
  64. if (clientProtocols.Contains(testProtocol))
  65. {
  66. return testProtocol;
  67. }
  68. }
  69. return string.Empty;
  70. }
  71. }