using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Primitives; using System.Net.WebSockets; using System.Text; namespace EVCB_OCPP.WSServer.Service.WsService; public static class AppExtention { public static void MapWsService(this WebApplication webApplication) { var protocals = new List() { "", "ocpp1.6", "ocpp2.0" }; webApplication.UseWebSockets(new WebSocketOptions() { KeepAliveInterval = TimeSpan.FromSeconds(10) }); webApplication.Use(async (context, next) => { 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>(); await servcie.AddWebSocket(webSocket, context); return; }); } } public class WebsocketService where T : WsSession { public WebsocketService() { } public Func> ValidateHandshake; public event EventHandler NewSessionConnected; public async Task AddWebSocket(WebSocket webSocket, HttpContext context) { T data = Activator.CreateInstance(); data.ClientWebSocket = webSocket; data.Path = context?.Request?.Path; data.UriScheme = context?.Request?.Scheme; data.AuthHeader = context?.Request?.Headers?.Authorization; data.SessionID = context.TraceIdentifier; data.Endpoint = null; data.Origin = context.Request.Headers.Origin; var validated = ValidateHandshake == null ? false : await ValidateHandshake(data); if (!validated) { return; } NewSessionConnected?.Invoke(this, data); await data.EndConnSemaphore.WaitAsync(); return; } } public enum CloseReason { ClientClosing, ServerShutdown }