public async Task Invoke( HttpContext httpContext, IChatroomsManager chatroomsManager, ILogger <WebSocketSession> logger) { if (httpContext is null) { throw new ArgumentNullException(nameof(httpContext)); } if (chatroomsManager is null) { throw new ArgumentNullException(nameof(chatroomsManager)); } if (!httpContext.WebSockets.IsWebSocketRequest || httpContext.Request.Path != ChatClientEndpoint) { await _next(httpContext); return; } if (logger is null) { throw new ArgumentNullException(nameof(logger)); } var webSocket = await httpContext.WebSockets.AcceptWebSocketAsync(); using var webSocketSession = new WebSocketSession(webSocket, _messageParser, logger); var connectionRequest = webSocketSession.ReceivedMessages .Where(msg => msg is ConnectionRequestMessage) .Timeout(_connectionTimeout, Observable.Return(ClientMessageBase.Empty)) .Take(1) .Wait() as ConnectionRequestMessage; if (connectionRequest is null) { httpContext.Response.StatusCode = StatusCodes.Status401Unauthorized; await httpContext.Response.CompleteAsync(); return; } httpContext.Request.Headers.Add(GetAuthorizationHeader(connectionRequest)); var authResults = await Task.WhenAll( httpContext.AuthenticateAsync(JwtSchemes.Admin), httpContext.AuthenticateAsync(JwtSchemes.User)); if (authResults.All(result => !result.Succeeded)) { await httpContext.Response.CompleteAsync(); return; } var sessionId = Guid.NewGuid(); using var chatClient = new NotificationClient( connectionRequest.UserId, sessionId, webSocketSession, chatroomsManager, _notificationsService); webSocketSession.EnqueueMessage(new ConnectedMessage { SessionId = sessionId, }); await webSocketSession.Lifetime.Task; }