Example #1
0
        private async Task ListenTo(string json)
        {
            bool    isValidJson = true;
            JObject jObject     = null;

            try
            {
                jObject = JObject.Parse(json);
            }
            catch (JsonReaderException)
            {
                isValidJson = false;
#if DEBUG
                Console.WriteLine($"Illegal JSON message: {json}");
#endif
            }

            if (!isValidJson)
            {
                return;
            }

            if (jObject["type"].Value <string>() == "message")
            {
                var          channelID = jObject["channel"].Value <string>();
                SlackChatHub hub       = null;

                if (ConnectedHubs.ContainsKey(channelID))
                {
                    hub = ConnectedHubs[channelID];
                }
                else
                {
                    hub = SlackChatHub.FromID(channelID);
                    var hubs = new Dictionary <string, SlackChatHub>(ConnectedHubs.ToDictionary(kvp => kvp.Key, kvp => kvp.Value));
                    hubs.Add(hub.ID, hub);
                    ConnectedHubs = hubs;
                }

                // some messages may not have text or a user (like unfurled data from URLs)
                var messageText = (jObject["text"] != null ? jObject["text"].Value <string>() : null);

                SlackMessage message = new SlackMessage()
                {
                    ChatHub = hub,
                    // check to see if bot has been mentioned
                    MentionsBot = (messageText != null ? Regex.IsMatch(messageText, BotNameRegex, RegexOptions.IgnoreCase) : false),
                    RawData     = json,
                    Text        = messageText,
                    User        = (jObject["user"] != null ? new SlackUser()
                    {
                        ID = jObject["user"].Value <string>()
                    } : null)
                };

                ResponseContext context = new ResponseContext()
                {
                    BotHasResponded = false,
                    BotUserID       = UserID,
                    BotUserName     = UserName,
                    Message         = message,
                    TeamID          = TeamID,
                    UserNameCache   = new ReadOnlyDictionary <string, string>(UserNameCache)
                };

                // if the end dev has added any static entries to the ResponseContext collection of Bot, add them to the context being passed to the responders.
                if (ResponseContext != null)
                {
                    foreach (string key in ResponseContext.Keys)
                    {
                        context.Set(key, ResponseContext[key]);
                    }
                }

                // margie can never respond to herself and requires that the message have text and be from an actual person
                if (message.User != null && message.User.ID != UserID && message.Text != null)
                {
                    foreach (var responder in Responders ?? Enumerable.Empty <IResponder>())
                    {
                        if (responder != null && responder.CanRespond(context))
                        {
                            await SendIsTyping(message.ChatHub);
                            await Say(responder.GetResponse(context), context);

                            context.BotHasResponded = true;
                        }
                    }
                }
            }

            RaiseMessageReceived(json);
        }
Example #2
0
        private async Task ListenTo(string json)
        {
            JObject jObject = JObject.Parse(json);

            if (jObject["type"].Value <string>() == "message")
            {
                string       channelID = jObject["channel"].Value <string>();
                SlackChatHub hub       = null;

                if (ConnectedHubs.ContainsKey(channelID))
                {
                    hub = ConnectedHubs[channelID];
                }
                else
                {
                    hub = SlackChatHub.FromID(channelID);
                    List <SlackChatHub> hubs = new List <SlackChatHub>();
                    hubs.AddRange(ConnectedHubs.Values);
                    hubs.Add(hub);
                }

                string messageText = (jObject["text"] != null ? jObject["text"].Value <string>() : null);
                // check to see if bot has been mentioned
                SlackMessage message = new SlackMessage()
                {
                    ChatHub     = hub,
                    MentionsBot = (messageText != null ? Regex.IsMatch(messageText, BotNameRegex, RegexOptions.IgnoreCase) : false),
                    RawData     = json,
                    // some messages may not have text or a user (like unfurled data from URLs)
                    Text = messageText,
                    User = (jObject["user"] != null ? new SlackUser()
                    {
                        ID = jObject["user"].Value <string>()
                    } : null)
                };

                ResponseContext context = new ResponseContext()
                {
                    BotHasResponded = false,
                    BotUserID       = UserID,
                    BotUserName     = UserName,
                    Message         = message,
                    TeamID          = this.TeamID,
                    UserNameCache   = new ReadOnlyDictionary <string, string>(this.UserNameCache)
                };

                if (StaticResponseContextData != null)
                {
                    foreach (string key in StaticResponseContextData.Keys)
                    {
                        context.Set(key, StaticResponseContextData[key]);
                    }
                }

                // margie can never respond to herself and requires that the message have text and be from an actual person
                if (message.User != null && message.User.ID != UserID && message.Text != null)
                {
                    foreach (IResponseProcessor processor in ResponseProcessors)
                    {
                        if (processor.CanRespond(context))
                        {
                            await Say(processor.GetResponse(context), context);

                            context.BotHasResponded = true;
                        }
                    }
                }
            }

            RaiseMessageReceived(json);
        }
Example #3
0
        private async Task ListenTo(string json)
        {
            JObject jObject = JObject.Parse(json);

            if (jObject["type"].Value <string>() == "message")
            {
                string       channelID = jObject["channel"].Value <string>();
                SlackChatHub hub       = null;

                if (ConnectedHubs.ContainsKey(channelID))
                {
                    hub = ConnectedHubs[channelID];
                }
                else
                {
                    hub = SlackChatHub.FromID(channelID);
                    Dictionary <string, SlackChatHub> hubs = new Dictionary <string, SlackChatHub>(ConnectedHubs.ToDictionary(kvp => kvp.Key, kvp => kvp.Value));
                    hubs.Add(hub.ID, hub);
                    ConnectedHubs = hubs;
                }

                string messageText = (jObject["text"] != null ? jObject["text"].Value <string>() : null);
                // check to see if bot has been mentioned
                SlackMessageContent message = new SlackMessageContent()
                {
                    ChatHub     = hub,
                    MentionsBot = (messageText != null ? Regex.IsMatch(messageText, BotNameRegex, RegexOptions.IgnoreCase) : false),
                    RawData     = json,
                    // some messages may not have text or a user (like unfurled data from URLs)
                    Text = messageText,
                    User = (jObject["user"] != null ? new SlackUser()
                    {
                        ID = jObject["user"].Value <string>()
                    } : null)
                };

                SlackMessage context = new SlackMessage()
                {
                    Creator         = this,
                    BotHasResponded = false,
                    BotUserID       = UserID,
                    BotUserName     = UserName,
                    Message         = message,
                    TeamID          = this.TeamID,
                    UserNameCache   = new ReadOnlyDictionary <string, string>(this.UserNameCache)
                };

                context.Answer = async(arg) =>
                {
                    await this.Say(arg, context);

                    context.BotHasResponded = true;
                };

                // if the end dev has added any static entries to the ResponseContext collection of Bot, add them to the context being passed to the responders.
                if (ResponseContext != null)
                {
                    foreach (string key in ResponseContext.Keys)
                    {
                        context.Set(key, ResponseContext[key]);
                    }
                }

                // margie can never respond to herself and requires that the message have text and be from an actual person
                if (message.User != null && message.User.ID != UserID && message.Text != null)
                {
                    foreach (var obs in observers)
                    {
                        obs.OnNext(context);
                    }
                }
            }

            RaiseMessageReceived(json);
        }
Example #4
0
        /// <summary>
        /// Listens to events sent from the rtm Interface. Uses a simple web socket to get the requests
        /// </summary>
        /// <param name="json">The json.</param>
        /// <returns></returns>
        private async Task ListenTo(string json)
        {
            ResponseContext context = null;
            JObject         jObject = JObject.Parse(json);

            if (jObject["type"] != null && jObject["type"].Value <string>() == "message")
            {
                string channelID = jObject["channel"].Value <string>();

                SlackMessage message = new SlackMessage()
                {
                    ChatHub     = null,
                    RawData     = json,
                    Attachments = new List <SlackAttachment>(),
                    Files       = new List <SlackFile>()
                };

                if (ConnectedHubs.ContainsKey(channelID))
                {
                    message.ChatHub = ConnectedHubs[channelID];
                }
                else
                {
                    message.ChatHub = SlackChatHub.FromID(channelID);
                    List <SlackChatHub> hubs = new List <SlackChatHub>();
                    hubs.AddRange(ConnectedHubs.Values);
                    hubs.Add(message.ChatHub);
                }

                try
                {
                    message.Text = (jObject["text"] != null ? jObject["text"].Value <string>() : string.Empty);

                    message.User = new SlackUser();
                    if (jObject["user"] != null)
                    {
                        WebClient client       = new WebClient();
                        string    responseJson = await client.GetResponse("https://slack.com/api/users.info?", WebClient.RequestMethod.Post, "token", this.SlackKey, "user", jObject["user"].Value <string>());

                        JObject jData = JObject.Parse(responseJson);

                        message.User.ID       = jObject["user"].Value <string>();
                        message.User.Name     = jData["user"]["real_name"].Value <string>();
                        message.User.ImageUrl = jData["user"]["profile"]["image_192"].Value <string>();
                    }
                    if (jObject["bot_id"] != null && jObject["username"] != null)
                    {
                        message.User.ID    = jObject["bot_id"].Value <string>();
                        message.User.IsBot = true;
                        message.User.Name  = jObject["username"].Value <string>();
                        if (!string.IsNullOrEmpty(message.User.ID) && !UserNameCache.ContainsKey(message.User.ID))
                        {
                            UserNameCache.Add(message.User.ID, message.User.Name);
                        }
                    }

                    if (jObject["attachments"] != null)
                    {
                        List <string> msg = new List <string>();

                        foreach (JObject attachment in jObject["attachments"])
                        {
                            SlackAttachment sla = new SlackAttachment()
                            {
                                Fallback = attachment["fallback"] != null ? attachment["fallback"].Value <string>() : string.Empty,
                                ColorHex = attachment["color"] != null ? attachment["color"].Value <string>(): string.Empty,
                                Text     = attachment["text"] != null ? attachment["text"].Value <string>() : string.Empty,
                                Title    = attachment["title"] != null? attachment["title"].Value <string>(): string.Empty,
                            };
                            message.Attachments.Add(sla);
                            msg.Add(sla.Title);
                            msg.Add(sla.Text);
                        }

                        if (string.IsNullOrEmpty(message.Text))
                        {
                            message.Text = string.Empty;
                        }

                        message.Text += string.Join(Environment.NewLine, msg);
                    }

                    if (jObject["files"] != null)
                    {
                        foreach (JObject file in jObject["files"])
                        {
                            message.Files.Add(new SlackFile()
                            {
                                Id          = file["id"]?.Value <string>() ?? string.Empty,
                                Name        = file["name"]?.Value <string>() ?? string.Empty,
                                Title       = file["title"]?.Value <string>() ?? string.Empty,
                                Filetype    = file["filetype"]?.Value <string>() ?? string.Empty,
                                Mimetype    = file["mimetype"]?.Value <string>() ?? string.Empty,
                                Size        = file["size"]?.Value <int>() ?? 0,
                                Permalink   = file["permalink"]?.Value <string>() ?? string.Empty,
                                Url_private = file["url_private"]?.Value <string>() ?? string.Empty
                            });
                        }
                    }


                    // check to see if bot has been mentioned
                    if (message.Text != null &&
                        Regex.IsMatch(message.Text, BotNameRegex, RegexOptions.IgnoreCase))
                    {
                        message.MentionsBot = true;
                    }

                    context = new ResponseContext()
                    {
                        BotHasResponded = false,
                        BotUserID       = UserID,
                        BotUserName     = UserName,
                        Message         = message,
                        TeamID          = this.TeamID,
                        UserNameCache   = new ReadOnlyDictionary <string, string>(this.UserNameCache),
                    };

                    // if the end dev has added any static entries to the ResponseContext collection of Bot, add them to the context being passed to the responders.
                    if (ResponseContext != null)
                    {
                        foreach (string key in ResponseContext.Keys)
                        {
                            context.Set(key, ResponseContext[key]);
                        }
                    }
                }
                catch (Exception ee)
                {
                    BotMessage errorMessage = new BotMessage()
                    {
                        ChatHub = message.ChatHub, Text = "ERROR parsing message : " + ee.Message + " " + ee.StackTrace
                    };
                    logger.Error(errorMessage.Text);
                    if (errorChannel != null)
                    {
                        //TODO
                        //await Say(errorMessage);
                    }
                }

                try
                {
                    // Avoid to answer to yourself
                    if (context != null && context.Message != null && context.Message.Text != null &&
                        !string.IsNullOrEmpty(context.Message.User.ID) && context.Message.User.ID != context.BotUserID)
                    {
                        foreach (IResponder responder in Responders)
                        {
                            if (responder.CanRespond(context))
                            {
                                await Say(responder.GetResponse(context), context);

                                context.BotHasResponded = true;
                            }
                        }
                    }
                }
                catch (Exception ee)
                {
                    BotMessage errorMessage = new BotMessage()
                    {
                        ChatHub = message.ChatHub, Text = "ERROR in responder: " + ee.Message + " " + ee.StackTrace
                    };
                    logger.Error(errorMessage.Text);
                    if (errorChannel != null)
                    {
                        //TODO
                        //await Say(errorMessage);
                    }
                }

                try
                {
                    RaiseMessageReceived(context);
                }
                catch (Exception ee)
                {
                    BotMessage errorMessage = new BotMessage()
                    {
                        ChatHub = message.ChatHub, Text = "ERROR with Message received event: " + ee.Message + " " + ee.StackTrace
                    };
                    logger.Error(errorMessage.Text);
                    if (errorChannel != null)
                    {
                        //TODO
                        //await Say(errorMessage);
                    }
                }
            }
        }
Example #5
0
        /// <summary>
        /// Connects the bot with the specified slack key.
        /// </summary>
        /// <returns></returns>
        public async Task Connect()
        {
            try
            {
                if (WebSocket != null && WebSocket.IsAlive)
                {
                    WebSocket.OnOpen    -= WebSocket_OnOpen;
                    WebSocket.OnMessage -= WebSocket_OnMessage;
                    WebSocket.OnError   -= WebSocket_OnError;
                    WebSocket.OnClose   -= WebSocket_OnClose;
                    WebSocket.Close();
                }

                // kill the regex for our bot's name - we'll rebuild it upon request with some of the info we get here
                BotNameRegex = string.Empty;

                WebClient client = new WebClient();

                string json = await client.GetResponse("https://slack.com/api/rtm.start", WebClient.RequestMethod.Post, "token", this.SlackKey);

                JObject jData = JObject.Parse(json);

                TeamID   = jData["team"]["id"].Value <string>();
                TeamName = jData["team"]["name"].Value <string>();
                UserID   = jData["self"]["id"].Value <string>();
                UserName = jData["self"]["name"].Value <string>();
                string webSocketUrl = jData["url"].Value <string>();

                UserNameCache.Clear();
                foreach (JObject userObject in jData["users"])
                {
                    UserNameCache.Add(userObject["id"].Value <string>(), userObject["name"].Value <string>());
                }

                // load the channels, groups, and DMs that margie's in
                Dictionary <string, SlackChatHub> hubs = new Dictionary <string, SlackChatHub>();
                ConnectedHubs = hubs;

                // channelz
                if (jData["channels"] != null)
                {
                    foreach (JObject channelData in jData["channels"])
                    {
                        if (!channelData["is_archived"].Value <bool>() && channelData["is_member"].Value <bool>())
                        {
                            SlackChatHub channel = new SlackChatHub()
                            {
                                ID   = channelData["id"].Value <string>(),
                                Name = "#" + channelData["name"].Value <string>(),
                                Type = SlackChatHubType.Channel
                            };
                            hubs.Add(channel.ID, channel);
                        }
                    }
                }

                // groupz
                if (jData["groups"] != null)
                {
                    foreach (JObject groupData in jData["groups"])
                    {
                        if (!groupData["is_archived"].Value <bool>() && groupData["members"].Values <string>().Contains(UserID))
                        {
                            SlackChatHub group = new SlackChatHub()
                            {
                                ID   = groupData["id"].Value <string>(),
                                Name = groupData["name"].Value <string>(),
                                Type = SlackChatHubType.Group
                            };
                            hubs.Add(group.ID, group);
                        }
                    }
                }

                // dmz
                if (jData["ims"] != null)
                {
                    foreach (JObject dmData in jData["ims"])
                    {
                        string       userID = dmData["user"].Value <string>();
                        SlackChatHub dm     = new SlackChatHub()
                        {
                            ID   = dmData["id"].Value <string>(),
                            Name = "@" + (UserNameCache.ContainsKey(userID) ? UserNameCache[userID] : userID),
                            Type = SlackChatHubType.DM
                        };
                        hubs.Add(dm.ID, dm);
                    }
                }

                // dmz
                if (jData["bots"] != null)
                {
                    foreach (JObject dmData in jData["bots"])
                    {
                        if (!dmData["deleted"].Value <bool>())
                        {
                            string       userID = dmData["id"].Value <string>();
                            SlackChatHub cbot   = new SlackChatHub()
                            {
                                ID   = dmData["id"].Value <string>(),
                                Name = "@" + (UserNameCache.ContainsKey(userID) ? UserNameCache[userID] : userID),
                                Type = SlackChatHubType.Bot
                            };
                            hubs.Add(cbot.ID, cbot);
                        }
                    }
                }

                if (!string.IsNullOrEmpty(this.ErrorMessageChannel) && ConnectedHubs.ContainsKey(this.ErrorMessageChannel))
                {
                    errorChannel = ConnectedHubs[this.ErrorMessageChannel];
                }

                WebSocket            = new WebSocket(webSocketUrl);
                WebSocket.OnOpen    += WebSocket_OnConnect;
                WebSocket.OnMessage += WebSocket_OnMessage;
                //WebSocket.OnError += WebSocket_OnError;
                //WebSocket.OnClose += WebSocket_OnClose;

                WebSocket.Connect();

                pinger = new Timer(TimerCallback, null, 0, 15000);
            }
            catch (Exception ee)
            {
                Disconnect();
            }
        }
        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);
        }