/// <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");
        }
Example #2
0
        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);
        }
Example #3
0
        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);
            }
        }