Exemple #1
0
        public Task StartAsync(CancellationToken cancellationToken)
        {
            log.LogInformation($"Start Gateway Service for {chainSettings.Symbol}.");

            tcpEndpoint = new IPEndPoint(IPAddress.Any, gatewaySettings.Port);
            tcp         = new TcpListener(tcpEndpoint);

            udpEndpoint = new IPEndPoint(IPAddress.Any, gatewaySettings.Port);
            udp         = new UdpClient(udpEndpoint);

            // To avoid circular reference we must resolve these in the startup.
            messageProcessing = serviceProvider.GetService <IGatewayMessageProcessing>();
            messageSerializer = serviceProvider.GetService <MessageSerializer>();

            // Prepare the messaging processors for message handling.
            MessageMaps maps = messageProcessing.Build();

            messageSerializer.Maps = maps;

            Task.Run(async() =>
            {
                try
                {
                    while (!cancellationToken.IsCancellationRequested)
                    {
                        Task tcpTask = Task.Run(() =>
                        {
                            TcpWorker(cancellationToken);
                        }, cancellationToken);

                        Task udTask = Task.Run(() =>
                        {
                            UdpWorker(cancellationToken);
                        }, cancellationToken);

                        Task.WaitAll(new Task[] { tcpTask, udTask }, cancellationToken);

                        //Task.Delay(TimeSpan.FromSeconds(retryInterval), cancellationToken).Wait(cancellationToken);

                        //var tokenSource = new CancellationTokenSource();
                        //cancellationToken.Register(() => { tokenSource.Cancel(); });

                        //try
                        //{
                        //   using (IServiceScope scope = scopeFactory.CreateScope())
                        //   {
                        //      Runner runner = scope.ServiceProvider.GetService<Runner>();
                        //      System.Collections.Generic.IEnumerable<Task> runningTasks = runner.RunAll(tokenSource);

                        //      Task.WaitAll(runningTasks.ToArray(), cancellationToken);

                        //      if (cancellationToken.IsCancellationRequested)
                        //      {
                        //         tokenSource.Cancel();
                        //      }
                        //   }

                        //   break;
                        //}
                        //catch (OperationCanceledException)
                        //{
                        //   // do nothing the task was cancel.
                        //   throw;
                        //}
                        //catch (AggregateException ae)
                        //{
                        //   if (ae.Flatten().InnerExceptions.OfType<SyncRestartException>().Any())
                        //   {
                        //      log.LogInformation("Sync: ### - Restart requested - ###");
                        //      log.LogTrace("Sync: Signalling token cancelation");
                        //      tokenSource.Cancel();

                        //      continue;
                        //   }

                        //   foreach (Exception innerException in ae.Flatten().InnerExceptions)
                        //   {
                        //      log.LogError(innerException, "Sync");
                        //   }

                        //   tokenSource.Cancel();

                        //   int retryInterval = 10;

                        //   log.LogWarning($"Unexpected error retry in {retryInterval} seconds");
                        //   //this.tracer.ReadLine();

                        //   // Blokcore Indexer is designed to be idempotent, we want to continue running even if errors are found.
                        //   // so if an unepxected error happened we log it wait and start again

                        //   Task.Delay(TimeSpan.FromSeconds(retryInterval), cancellationToken).Wait(cancellationToken);

                        //   continue;
                        //}
                        //catch (Exception ex)
                        //{
                        //   log.LogError(ex, "Sync");
                        //   break;
                        //}
                    }
                }
                catch (OperationCanceledException)
                {
                    // do nothing the task was cancel.
                    throw;
                }
                catch (Exception ex)
                {
                    log.LogError(ex, "Gateway");
                    throw;
                }
            }, cancellationToken);

            return(Task.CompletedTask);
        }
        public Task StartAsync(CancellationToken cancellationToken)
        {
            log.LogInformation($"Start Hub Service for {chainSettings.Symbol}.");

            Protection    protection = new Protection();
            Mnemonic      recoveryPhrase;
            DirectoryInfo dataFolder = new DirectoryInfo(hubSettings.DataFolder);

            if (!dataFolder.Exists)
            {
                dataFolder.Create();
            }

            string path = Path.Combine(dataFolder.FullName, "recoveryphrase.txt");

            if (!File.Exists(path))
            {
                recoveryPhrase = new Mnemonic(Wordlist.English, WordCount.Twelve);
                string cipher = protection.Protect(recoveryPhrase.ToString());
                File.WriteAllText(path, cipher);
            }
            else
            {
                string cipher = File.ReadAllText(path);
                recoveryPhrase = new Mnemonic(protection.Unprotect(cipher));
            }

            if (recoveryPhrase.ToString() != "border indicate crater public wealth luxury derive media barely survey rule hen")
            {
                //throw new ApplicationException("RECOVERY PHRASE IS DIFFERENT!");
            }

            // Read the identity from the secure storage and provide it here.
            //host.Setup(new Identity(recoveryPhrase.ToString()), stoppingToken);


            IPAddress[] IPAddresses = Dns.GetHostAddresses(hubSettings.Server);

            if (IPAddresses.Length == 0)
            {
                throw new ApplicationException("Did not find any IP address for the hub server.");
            }

            //ServerEndpoint = new IPEndPoint(IPAddress.Parse(hubSettings.Server), hubSettings.Port);
            // TODO: #4
            ServerEndpoint = new IPEndPoint(IPAddresses[0], hubSettings.Port);
            LocalHubInfo   = new HubInfo();
            AckResponces   = new List <Ack>();

            UDPClientGateway.AllowNatTraversal(true);
            UDPClientGateway.Client.SetIPProtectionLevel(IPProtectionLevel.Unrestricted);
            UDPClientGateway.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);

            LocalHubInfo.Name           = Environment.MachineName;
            LocalHubInfo.ConnectionType = ConnectionTypes.Unknown;
            LocalHubInfo.Id             = Guid.NewGuid().ToString();
            //LocalHubInfo.Id = DateTime.Now.Ticks;

            IEnumerable <IPAddress> IPs = Dns.GetHostEntry(Dns.GetHostName()).AddressList.Where(ip => ip.AddressFamily == AddressFamily.InterNetwork);

            foreach (IPAddress IP in IPs)
            {
                log.LogInformation("Internal Address: {IP}", IP);
                LocalHubInfo.InternalAddresses.Add(IP);
            }

            // To avoid circular reference we must resolve these in the startup.
            messageProcessing = serviceProvider.GetService <IHubMessageProcessing>();
            messageSerializer = serviceProvider.GetService <MessageSerializer>();

            // Prepare the messaging processors for message handling.
            MessageMaps maps = messageProcessing.Build();

            messageSerializer.Maps = maps;

            hub.Subscribe <ConnectionAddedEvent>(this, e =>
            {
                StringBuilder entry = new StringBuilder();

                entry.AppendLine($"ConnectionAddedEvent: {e.Data.Id}");
                entry.AppendLine($"                    : ExternalIPAddress: {e.Data.ExternalEndpoint}");
                entry.AppendLine($"                    : InternalIPAddress: {e.Data.InternalEndpoint}");
                entry.AppendLine($"                    : Name: {e.Data.Name}");

                foreach (System.Net.IPAddress address in e.Data.InternalAddresses)
                {
                    entry.AppendLine($"                    : Address: {address}");
                }

                log.LogInformation(entry.ToString());

                //var msg = new MessageModel
                //{
                //   Type = "ConnectionAddedEvent",
                //   Date = DateTime.UtcNow,
                //   Message = entry.ToString(),
                //   Data = e
                //};

                hubContext.Clients.All.SendAsync("Event", e);
            });

            hub.Subscribe <ConnectionRemovedEvent>(this, e =>
            {
                log.LogInformation($"ConnectionRemovedEvent: {e.Data.Id}");

                log.LogInformation($"ConnectionRemovedEvent: {e.Data.Id}");

                if (ConnectedHubs.ContainsKey(e.Data.Id))
                {
                    ConnectedHubs.Remove(e.Data.Id);
                }


                //var msg = new MessageModel
                //{
                //   Type = "ConnectionRemovedEvent",
                //   Date = DateTime.UtcNow,
                //   Message = e.Data.ToString(),
                //   Data = e.Data
                //};



                hubContext.Clients.All.SendAsync("Event", e);
            });

            hub.Subscribe <ConnectionStartedEvent>(this, e =>
            {
                log.LogInformation($"ConnectionStartedEvent: {e.Endpoint}");

                //var msg = new MessageModel
                //{
                //   Type = "ConnectionStartedEvent",
                //   Date = DateTime.UtcNow,
                //   Message = e.Endpoint.ToString(),
                //   Data = e.Endpoint.ToString()
                //};

                hubContext.Clients.All.SendAsync("Event", e);
            });

            hub.Subscribe <ConnectionStartingEvent>(this, e =>
            {
                log.LogInformation($"ConnectionStartingEvent: {e.Data.Id}");

                //var msg = new MessageModel
                //{
                //   Type = "ConnectionStartingEvent",
                //   Date = DateTime.UtcNow,
                //   Message = e.Data.Id.ToString(),
                //   Data = e.Data.Id.ToString()
                //};

                hubContext.Clients.All.SendAsync("Event", e);
            });

            hub.Subscribe <ConnectionUpdatedEvent>(this, e =>
            {
                log.LogInformation($"ConnectionUpdatedEvent: {e.Data.Id}");

                //var msg = new MessageModel
                //{
                //   Type = "ConnectionUpdatedEvent",
                //   Date = DateTime.UtcNow,
                //   Message = e.Data.Id.ToString(),
                //   Data = e.Data.Id
                //};

                hubContext.Clients.All.SendAsync("Event", e);

                // Automatically connect to discovered hubs.
                if (LocalHubInfo.Id != e.Data.Id)
                {
                    ConnectToClient(e.Data);
                }
            });

            hub.Subscribe <GatewayConnectedEvent>(this, e =>
            {
                log.LogInformation("Connected to Gateway");

                //var msg = new MessageModel
                //{
                //   Type = "GatewayConnectedEvent",
                //   Date = DateTime.UtcNow,
                //   Message = "",
                //   Data = ""
                //};

                hubContext.Clients.All.SendAsync("Event", e);
            });

            hub.Subscribe <GatewayShutdownEvent>(this, e =>
            {
                log.LogInformation("Disconnected from Gateway");

                //var msg = new MessageModel
                //{
                //   Type = "GatewayShutdownEvent",
                //   Date = DateTime.UtcNow,
                //   Message = "",
                //   Data = ""
                //};

                hubContext.Clients.All.SendAsync("Event", e);
            });

            hub.Subscribe <HubInfoEvent>(this, e =>
            {
                //var msg = new MessageModel
                //{
                //   Type = "HubInfoEvent",
                //   Date = DateTime.UtcNow,
                //   Message = e.Data.ToString(),
                //   Data = e.Data
                //};

                //if (e.Data.Id == Identity.Id)
                //{
                //   return;
                //}

                AvailableHubs.Add(e.Data.Id, new HubInfo(e.Data));

                hubContext.Clients.All.SendAsync("Event", e);
            });

            hub.Subscribe <MessageReceivedEvent>(this, e =>
            {
                log.LogInformation($"MessageReceivedEvent: {e.Data.Content}");

                //var msg = new MessageModel
                //{
                //   Type = "MessageReceivedEvent",
                //   Date = DateTime.UtcNow,
                //   Message = e.Data.Content,
                //   Data = e.Data.Content
                //};

                hubContext.Clients.All.SendAsync("Event", e);
            });

            hub.Subscribe <GatewayErrorEvent>(this, e =>
            {
                log.LogInformation($"GatewayErrorEvent: {e.Message}");

                //var msg = new MessageModel
                //{
                //   Type = "GatewayErrorEvent",
                //   Date = DateTime.UtcNow,
                //   Message = e.Message,
                //   Data = e.Message
                //};

                hubContext.Clients.All.SendAsync("Event", e);
            });

            Task.Run(async() =>
            {
                try
                {
                    bool connectedToGateway = false;

                    while (!cancellationToken.IsCancellationRequested)
                    {
                        //Task tcpTask = Task.Run(() =>
                        //{
                        //   TcpWorker(cancellationToken);
                        //}, cancellationToken);

                        //Task udTask = Task.Run(() =>
                        //{
                        //   UdpWorker(cancellationToken);
                        //}, cancellationToken);

                        //Task.WaitAll(new Task[] { tcpTask, udTask }, cancellationToken);

                        if (!connectedToGateway)
                        {
                            connectedToGateway = ConnectGateway();
                        }

                        // TODO: This loop will just continue to run after connected to gateway. It should check status and attempt to recycle and reconnect when needed.
                        Task.Delay(TimeSpan.FromSeconds(retryInterval), cancellationToken).Wait(cancellationToken);

                        //Task.Delay(TimeSpan.FromSeconds(retryInterval), cancellationToken).Wait(cancellationToken);

                        //var tokenSource = new CancellationTokenSource();
                        //cancellationToken.Register(() => { tokenSource.Cancel(); });

                        //try
                        //{
                        //   using (IServiceScope scope = scopeFactory.CreateScope())
                        //   {
                        //      Runner runner = scope.ServiceProvider.GetService<Runner>();
                        //      System.Collections.Generic.IEnumerable<Task> runningTasks = runner.RunAll(tokenSource);

                        //      Task.WaitAll(runningTasks.ToArray(), cancellationToken);

                        //      if (cancellationToken.IsCancellationRequested)
                        //      {
                        //         tokenSource.Cancel();
                        //      }
                        //   }

                        //   break;
                        //}
                        //catch (OperationCanceledException)
                        //{
                        //   // do nothing the task was cancel.
                        //   throw;
                        //}
                        //catch (AggregateException ae)
                        //{
                        //   if (ae.Flatten().InnerExceptions.OfType<SyncRestartException>().Any())
                        //   {
                        //      log.LogInformation("Sync: ### - Restart requested - ###");
                        //      log.LogTrace("Sync: Signalling token cancelation");
                        //      tokenSource.Cancel();

                        //      continue;
                        //   }

                        //   foreach (Exception innerException in ae.Flatten().InnerExceptions)
                        //   {
                        //      log.LogError(innerException, "Sync");
                        //   }

                        //   tokenSource.Cancel();

                        //   int retryInterval = 10;

                        //   log.LogWarning($"Unexpected error retry in {retryInterval} seconds");
                        //   //this.tracer.ReadLine();

                        //   // Blokcore Indexer is designed to be idempotent, we want to continue running even if errors are found.
                        //   // so if an unepxected error happened we log it wait and start again

                        //   Task.Delay(TimeSpan.FromSeconds(retryInterval), cancellationToken).Wait(cancellationToken);

                        //   continue;
                        //}
                        //catch (Exception ex)
                        //{
                        //   log.LogError(ex, "Sync");
                        //   break;
                        //}
                    }
                }
                catch (OperationCanceledException)
                {
                    // do nothing the task was cancel.
                    throw;
                }
                catch (Exception ex)
                {
                    log.LogError(ex, "Gateway");
                    throw;
                }
            }, cancellationToken);

            return(Task.CompletedTask);
        }