Ejemplo n.º 1
0
        static async Task WhenConnectionIsBrokenAsync(this ManagedWebSocket websocket)
        {
            // prepare
            websocket.SetStatus("Disconnected");
            websocket.Remove("Session", out Session session);
            var correlationID = UtilityService.NewUUID;

            // remove the updater
            if (websocket.Remove("Updater", out IDisposable updater))
            {
                try
                {
                    updater?.Dispose();
                }
                catch (Exception ex)
                {
                    await Global.WriteLogsAsync(RTU.Logger, "Http.InternalAPIs", $"Error occurred while disposing updater: {session?.ToJson()?.ToString(Global.IsDebugResultsEnabled ? Formatting.Indented : Formatting.None)}", ex, Global.ServiceName, LogLevel.Error, correlationID).ConfigureAwait(false);
                }
            }

            // remove the communicator
            if (websocket.Remove("Communicator", out IDisposable communicator))
            {
                try
                {
                    communicator?.Dispose();
                }
                catch (Exception ex)
                {
                    await Global.WriteLogsAsync(RTU.Logger, "Http.InternalAPIs", $"Error occurred while disposing communicator: {session?.ToJson()?.ToString(Global.IsDebugResultsEnabled ? Formatting.Indented : Formatting.None)}", ex, Global.ServiceName, LogLevel.Error, correlationID).ConfigureAwait(false);
                }
            }

            // update the session state
            await Task.WhenAll(
                session != null?session.SendSessionStateAsync(false, correlationID) : Task.CompletedTask,
                Global.IsVisitLogEnabled?Global.WriteLogsAsync(RTU.Logger, "Http.Visits", $"The real-time updater (RTU) is stopped" + "\r\n" + websocket.GetConnectionInfo(session) + "\r\n" + $"- Served times: {websocket.Timestamp.GetElapsedTimes()}", null, Global.ServiceName, LogLevel.Information, correlationID) : Task.CompletedTask
                ).ConfigureAwait(false);
        }
Ejemplo n.º 2
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);
            }
        }