Эх сурвалжийг харах

add ocpp portocol version check handler

Robert 1 жил өмнө
parent
commit
8212d45f27

+ 1 - 1
EVCB_OCPP.WSServer/HostedProtalServer.cs

@@ -20,7 +20,7 @@ namespace EVCB_OCPP.WSServer
             services.AddPortalServerDatabase(configuration);
             services.AddBusinessServiceFactory();
 
-            services.AddSingleton<WebsocketService<WsClientData>>();
+            services.AddSingleton<OcppWebsocketService>();
 
             services.AddSingleton<ServerMessageService>();
             services.AddSingleton<LoadingBalanceService>();

+ 1 - 1
EVCB_OCPP.WSServer/Program.cs

@@ -51,7 +51,7 @@ namespace EVCB_OCPP.WSServer
                     //services.AddTransient<GoogleGetTimePrintService>();
                 });
             var app = builder.Build();
-            app.MapWsService();
+            app.MapOcppWsService();
             app.MapApiServce();
             app.Urls.Add("http://*:80");
             app.Run();

+ 2 - 2
EVCB_OCPP.WSServer/ProtalServer.cs

@@ -51,7 +51,7 @@ namespace EVCB_OCPP.WSServer
             , ServerMessageService serverMessageService
             , WebDbService webDbService
             , ProfileHandler profileHandler
-            , WebsocketService<WsClientData> websocketService
+            , OcppWebsocketService websocketService
             , OuterHttpClient httpClient)
         {
             this.logger = logger;
@@ -82,7 +82,7 @@ namespace EVCB_OCPP.WSServer
         private readonly IConnectionLogdbService connectionLogdbService;
         private readonly WebDbService webDbService;
         private readonly ProfileHandler profileHandler;
-        private readonly WebsocketService<WsClientData> websocketService;
+        private readonly OcppWebsocketService websocketService;
         private readonly bool isInDocker;
         private List<NeedConfirmMessage> needConfirmPacketList = new List<NeedConfirmMessage>();
         private DateTime checkUpdateDt = DateTime.UtcNow;

+ 61 - 0
EVCB_OCPP.WSServer/Service/WsService/OcppWebsocketService.cs

@@ -0,0 +1,61 @@
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Http;
+using Microsoft.Extensions.DependencyInjection;
+using System.Net.WebSockets;
+
+namespace EVCB_OCPP.WSServer.Service.WsService;
+
+public static class AppExtention
+{
+    public static void MapOcppWsService(this WebApplication webApplication)
+    {
+        webApplication.UseWebSockets(new WebSocketOptions()
+        {
+            KeepAliveInterval = TimeSpan.FromSeconds(10)
+        });
+
+        webApplication.Use(async (context, next) =>
+        {
+            if (!context.WebSockets.IsWebSocketRequest)
+            {
+                await next(context);
+                return;
+            }
+
+            var servcie = context.RequestServices.GetService<OcppWebsocketService>();
+            await servcie.AcceptWebSocket(context);
+            return;
+        });
+    }
+}
+
+public class OcppWebsocketService : WebsocketService<WsClientData>
+{
+    public static List<string> protocals = new List<string>() { "", "ocpp1.6", "ocpp2.0.1" };
+
+    internal override async ValueTask<string> AcceptWebSocketHandler(HttpContext context)
+    {
+        var protocol = GetSupportedPortocol(context.WebSockets.WebSocketRequestedProtocols, protocals);
+        if (string.IsNullOrEmpty(protocol))
+        {
+            using WebSocket toRejectwebSocket = await context.WebSockets.AcceptWebSocketAsync();
+            await toRejectwebSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, null, default);
+            return string.Empty;
+        }
+        return protocol;
+    }
+
+    private static string GetSupportedPortocol(IList<string> clientProtocols, IList<string> supportedProtocols)
+    {
+        int supportedProtocolIndex = supportedProtocols.Count - 1;
+        for (; supportedProtocolIndex >= 0; supportedProtocolIndex--)
+        {
+            var testProtocol = supportedProtocols[supportedProtocolIndex];
+            if (clientProtocols.Contains(testProtocol))
+            {
+                return testProtocol;
+            }
+        }
+        return string.Empty;
+    }
+}

+ 22 - 44
EVCB_OCPP.WSServer/Service/WsService/WebsocketService.cs

@@ -1,55 +1,39 @@
-using Microsoft.AspNetCore.Builder;
-using Microsoft.AspNetCore.Http;
-using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Primitives;
+using Microsoft.AspNetCore.Http;
 using System.Net;
 using System.Net.WebSockets;
-using System.Text;
-using static System.Runtime.InteropServices.JavaScript.JSType;
 
 namespace EVCB_OCPP.WSServer.Service.WsService;
 
-public static class AppExtention
+public class WebsocketService<T> where T : WsSession
 {
-    public static void MapWsService(this WebApplication webApplication)
-    {
-        var protocals = new List<string>() { "", "ocpp1.6", "ocpp2.0" };
+    public WebsocketService() { }
 
-        webApplication.UseWebSockets(new WebSocketOptions()
-        {
-            KeepAliveInterval = TimeSpan.FromSeconds(10)
-        });
+    public Func<T, Task<bool>> ValidateHandshake;
+
+    public event EventHandler<T> NewSessionConnected;
 
-        webApplication.Use(async (context, next) =>
+    public async Task AcceptWebSocket(HttpContext context)
+    {
+        if (!context.WebSockets.IsWebSocketRequest)
         {
+            return;
+        }
 
-            if (!context.WebSockets.IsWebSocketRequest)
-            {
-                await next(context);
-                return;
-            }
-
-            var matched = context.WebSockets.WebSocketRequestedProtocols.Intersect(protocals);
-            if (matched is null || !matched.Any())
-            {
-                await context.Response.WriteAsync("Protocol not matched");
-                return;
-            }
-            using WebSocket webSocket = await context.WebSockets.AcceptWebSocketAsync(matched.Last());
-            var servcie = context.RequestServices.GetService<WebsocketService<WsClientData>>();
-            await servcie.AddWebSocket(webSocket, context);
+        var portocol = await AcceptWebSocketHandler(context);
+        if (string.IsNullOrEmpty(portocol))
+        {
             return;
-        });
-    }
-}
+        }
 
-public class WebsocketService<T> where T : WsSession
-{
-    public WebsocketService() { }
+        using WebSocket webSocket = await context.WebSockets.AcceptWebSocketAsync(portocol);
+        await AddWebSocket(webSocket, context);
+    }
 
-    public Func<T, Task<bool>> ValidateHandshake;
+    internal virtual ValueTask<string> AcceptWebSocketHandler(HttpContext context)
+    {
+        return ValueTask.FromResult(string.Empty);
+    }
 
-    public event EventHandler<T> NewSessionConnected;
 
     public async Task AddWebSocket(WebSocket webSocket, HttpContext context)
     {
@@ -109,10 +93,4 @@ public class WebsocketService<T> where T : WsSession
 
         return toReturn;
     }
-}
-
-public enum CloseReason
-{
-    ClientClosing,
-    ServerShutdown
 }