1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980 |
- 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<string>() { "", "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<WebsocketService<WsClientData>>();
- await servcie.AddWebSocket(webSocket, context);
- return;
- });
- }
- }
- public class WebsocketService<T> where T : WsSession
- {
- public WebsocketService() { }
- public Func<T, Task<bool>> ValidateHandshake;
- public event EventHandler<T> NewSessionConnected;
- public async Task AddWebSocket(WebSocket webSocket, HttpContext context)
- {
- T data = Activator.CreateInstance<T>();
- 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
- }
|