/// <summary> /// Prepares the information of the connection /// </summary> /// <param name="websocket"></param> /// <param name="correlationID"></param> /// <param name="session"></param> /// <param name="cancellationToken"></param> /// <param name="logger"></param> /// <returns></returns> public static async Task PrepareConnectionInfoAsync(this ManagedWebSocket websocket, string correlationID = null, Session session = null, CancellationToken cancellationToken = default, Microsoft.Extensions.Logging.ILogger logger = null) { correlationID = correlationID ?? UtilityService.NewUUID; session = session ?? websocket.Get <Session>("Session"); var account = "Visitor"; if (!string.IsNullOrWhiteSpace(session?.User?.ID)) { try { var json = await Router.GetService("Users").ProcessRequestAsync(new RequestInfo(session, "Users", "Profile", "GET") { CorrelationID = correlationID }, cancellationToken).ConfigureAwait(false); account = $"{json?.Get<string>("Name") ?? "Unknown"} ({session.User.ID})"; } catch (Exception ex) { account = $"Unknown ({session.User.ID})"; logger?.LogError($"Error occurred while fetching an account profile => {ex.Message}", ex); } } websocket.Set("AccountInfo", account); websocket.Set("LocationInfo", session != null ? await session.GetLocationAsync(correlationID, cancellationToken).ConfigureAwait(false) : "Unknown"); }
public void OnConnection(ManagedWebSocket client) { if (!VerifyClient(client)) { client.CloseAsync(System.Net.WebSockets.WebSocketCloseStatus.InternalServerError, "Connection rejected", CancellationToken.None); } var newConnection = new Connection(this, client); client.Set("agar", newConnection); Console.WriteLine($"CONNECTION FROM {newConnection.RemoteAddress}"); connections.Add(newConnection); }
static async Task WhenConnectionIsEstablishedAsync(this ManagedWebSocket websocket) { // update status websocket.SetStatus("Initializing"); var correlationID = UtilityService.NewUUID; // prepare session try { var query = websocket.RequestUri.ParseQuery(); var session = Global.GetSession(websocket.Headers, query, $"{(websocket.RemoteEndPoint as IPEndPoint).Address}"); // update session identity session.SessionID = query.TryGetValue("x-session-id", out var sessionID) ? sessionID.Url64Decode() : ""; if (string.IsNullOrWhiteSpace(session.SessionID)) { throw new InvalidRequestException("Session identity is not found"); } // update device identity session.DeviceID = query.TryGetValue("x-device-id", out var deviceID) ? deviceID.Url64Decode() : ""; if (string.IsNullOrWhiteSpace(session.DeviceID)) { throw new InvalidRequestException("Device identity is not found"); } // update session websocket.Set("Session", session); await websocket.PrepareConnectionInfoAsync(correlationID, session, Global.CancellationTokenSource.Token, RTU.Logger).ConfigureAwait(false); // wait for few times before connecting to API Gateway Router because RxNET needs that if (query.ContainsKey("x-restart")) { await Task.WhenAll( websocket.SendAsync(new UpdateMessage { Type = "Knock" }), Task.Delay(345, Global.CancellationTokenSource.Token) ).ConfigureAwait(false); } } catch (Exception ex) { await RTU.WebSocket.CloseWebSocketAsync(websocket, ex is InvalidRequestException?WebSocketCloseStatus.InvalidPayloadData : WebSocketCloseStatus.InternalServerError, ex is InvalidRequestException?$"Request is invalid => {ex.Message}" : ex.Message).ConfigureAwait(false); return; } // subscribe an updater to push messages to client device websocket.Set("Updater", Services.Router.IncomingChannel.RealmProxy.Services .GetSubject <UpdateMessage>("messages.update") .Subscribe( async message => await websocket.PushAsync(message).ConfigureAwait(false), async exception => await Global.WriteLogsAsync(RTU.Logger, "Http.InternalAPIs", $"Error occurred while fetching an updating message => {exception.Message}", exception).ConfigureAwait(false) ) ); // subscribe a communicator to update related information websocket.Set("Communicator", Services.Router.IncomingChannel.RealmProxy.Services .GetSubject <CommunicateMessage>("messages.services.apigateway") .Subscribe( async message => await websocket.CommunicateAsync(message).ConfigureAwait(false), async exception => await Global.WriteLogsAsync(RTU.Logger, "Http.InternalAPIs", $"Error occurred while fetching an inter-communicating message => {exception.Message}", exception).ConfigureAwait(false) ) ); // update status websocket.SetStatus("Connected"); if (Global.IsVisitLogEnabled) { await Global.WriteLogsAsync(RTU.Logger, "Http.Visits", $"The real-time updater (RTU) is started" + "\r\n" + websocket.GetConnectionInfo() + "\r\n" + $"- Status: {websocket.GetStatus()}", null, Global.ServiceName, LogLevel.Information, correlationID).ConfigureAwait(false); } }