using Microsoft.AspNetCore.Http; using System.Net; using System.Net.WebSockets; namespace EVCB_OCPP.WSServer.Service.WsService; public class WebsocketService where T : WsSession { public WebsocketService() { } public Func> ValidateHandshake; public event EventHandler NewSessionConnected; public async Task AcceptWebSocket(HttpContext context) { if (!context.WebSockets.IsWebSocketRequest) { return; } var portocol = await AcceptWebSocketHandler(context); if (string.IsNullOrEmpty(portocol)) { return; } using WebSocket webSocket = await context.WebSockets.AcceptWebSocketAsync(portocol); await AddWebSocket(webSocket, context); } internal virtual ValueTask AcceptWebSocketHandler(HttpContext context) { return ValueTask.FromResult(string.Empty); } public async Task AddWebSocket(WebSocket webSocket, HttpContext context) { T data = Activator.CreateInstance(); data.ClientWebSocket = webSocket; data.SessionID = context.TraceIdentifier; data.Path = context?.Request?.Path; //data.UriScheme = context?.Request?.Scheme; data.AuthHeader = context?.Request?.Headers?.Authorization; //data.Origin = context.Request.Scheme; data.UriScheme = GetScheme(context); try { var ipaddress = context.Connection.RemoteIpAddress; var port = context.Connection.RemotePort; data.Endpoint = new IPEndPoint(ipaddress, port); } catch { data.Endpoint = null; } var validated = ValidateHandshake == null ? false : await ValidateHandshake(data); if (!validated) { return; } NewSessionConnected?.Invoke(this, data); await data.EndConnSemaphore.WaitAsync(); return; } private string GetScheme(HttpContext context) { string toReturn = string.Empty; if (context.Request.Headers.ContainsKey("x-original-host")) { toReturn = new Uri(context.Request.Headers["x-original-host"]).Scheme; return toReturn; } var origin = context.Request.Headers.Origin.FirstOrDefault(); try { toReturn = new Uri(origin).Scheme; return toReturn; } catch { } return toReturn; } }