private Packet DoRecieve(MQTTClient mqttClient, IEnumerable<byte> dataBytes, out bool disconnect)
        {
            // declare hub
            var hubContext = GlobalHost.ConnectionManager.GetHubContext<BrokerHub>();

            List<byte> byteList = dataBytes.ToList();
            MQTTPacketTypes mqttPacketType = (MQTTPacketTypes)byteList.First();
            disconnect = false;
            string data = string.Empty;
            Packet responsePacket = null;
            Console.ForegroundColor = ConsoleColor.Red;
            switch (mqttPacketType)
            {
                // types we should recieve
                case MQTTPacketTypes.PUBLISH:
                    Console.WriteLine("PUBLISH recieved");
                    var pubPacket = new Publish(byteList);
                    PublishToAllClients(pubPacket.TopicName, pubPacket.Payload);
                    data = string.Format("Topic: {0} Data: {1}", pubPacket.TopicName, pubPacket.Payload);
                    // responsePacket = new Puback();
                    break;
                case MQTTPacketTypes.DISCONNECT:
                    Console.WriteLine("DISCONNECT recieved");
                    disconnect = true; // handle at the higher level
                    MQTTClient temp;
                    if (!ClientCollection.TryRemove(mqttClient.UniqueId, out temp))
                    {
                        //Trace.WriteLine("Error occurred removing client from client collection");
                    }
                    hubContext.Clients.All.clientDisconnected(mqttClient.UniqueId);
                    break;
                case MQTTPacketTypes.PINGREQ:
                    Console.WriteLine("PINGREQ recieved");
                    var pingRespPacket = new Pingresp();
                    responsePacket = pingRespPacket;
                    break;
                case MQTTPacketTypes.UNSUBSCRIBE:
                    Console.WriteLine("UNSUBSCRIBE recieved");
                    var unsubPacket = new Unsubscribe((List<byte>)dataBytes);

                    string summaryString = string.Empty;
                    foreach (var topic in unsubPacket.TopicNames)
                    {
                        hubContext.Clients.All.removeSubscription(mqttClient.UniqueId, topic);
                        summaryString += topic + " ";
                    }

                    data = string.Format("Topics: {0}",summaryString);

                    // remove all subscriptions in unsubscribe
                    mqttClient.SubscriptionList = mqttClient.SubscriptionList.Except(unsubPacket.TopicNames).ToList();

                    var unsubackPacket = new Unsuback(unsubPacket.PacketId);
                    responsePacket = unsubackPacket;
                    break;
                case MQTTPacketTypes.SUBSCRIBE:
                    Console.WriteLine("SUBSCRIBE recieved");
                    var subPacket = new Subscribe((List<byte>)dataBytes);

                    List<int> subSuccess = new List<int>();
                    foreach (var item in subPacket.subList)
                    {
                        if(!mqttClient.SubscriptionList.Contains(item.Name))
                        {
                            mqttClient.SubscriptionList.Add(item.Name);
                            subSuccess.Add(1);
                        }
                        else
                            subSuccess.Add(0);
                    }
                    string summaryString2 = string.Empty;
                    foreach (var topic in subPacket.subList)
                    {
                        hubContext.Clients.All.addSubscription(mqttClient.UniqueId, topic.Name);
                        summaryString2 += topic.Name + " ";
                    }

                    data = string.Format("Topics: {0}",summaryString2);

                    var subAckPacket = new Suback(subPacket.PacketId, subSuccess.ToArray());
                    responsePacket = subAckPacket;
                    break;
                case MQTTPacketTypes.CONNECT:
                    Console.WriteLine("CONNECT recieved");
                    var connectPacket = new Connect((List<byte>)dataBytes);
                    mqttClient.ClientID = connectPacket.ClientId;
                    ClientCollection.GetOrAdd(clientCounter, mqttClient);
                    hubContext.Clients.All.newClientConnected(mqttClient);
                    responsePacket = new Connack();
                    break;
                // types we should NOT recieve
                case MQTTPacketTypes.CONNACK:
                    Console.WriteLine("CONNACK recieved");
                    break;
                case MQTTPacketTypes.SUBACK:
                    Console.WriteLine("SUBACK recieved");
                    break;
                case MQTTPacketTypes.PINGRESP:
                    Console.WriteLine("PINGRESP recieved");
                    break;
                case MQTTPacketTypes.UNSUBACK:
                    Console.WriteLine("UNSUBACK recieved");
                    break;
                default:
                    Console.WriteLine("Unknown packet recieved");
                    break;

            }
            Console.ResetColor();
            hubContext.Clients.All.newPacketRecieved(true, mqttClient.UniqueId, Enum.GetName(typeof(MQTTPacketTypes), mqttPacketType), data, DateTime.Now.ToLongTimeString());
            return responsePacket;
        }
        private void ListenForClients()
        {
            listener = new CustomTcpListener(IPAddress.Any, int.Parse(ConfigurationManager.AppSettings["mqttPort"]));
            try
            {
                if (!listener.Active)
                    listener.Start();
            }
            catch (Exception ex)
            {
                // no idea why this breaks sometimes but not always
                Trace.WriteLine(ex.Message);
            }

            while (_runBroker)
            {
                TcpClient client = null;

                try
                {
                    // this avoids the blocking call for the listener so we can safely end the thread
                    if (listener.Pending())
                        client = listener.AcceptTcpClient();
                    else
                    {
                        Thread.Sleep(THREAD_SLEEP_REST_TIME);
                        continue;
                    }

                }
                catch (SocketException)
                {
                    //welp
                }

                if (client != null)
                {
                    var ipAddressOfClient = ((IPEndPoint)client.Client.RemoteEndPoint).Address.ToString();

                    MQTTClient mqttClient = new MQTTClient()
                    {
                        UniqueId = ++clientCounter,
                        TCPClient = client,
                        IPAddress = ipAddressOfClient,
                        LastContactTime = DateTime.Now
                    };

                    Thread clientThread = new Thread(() => HandleClient(mqttClient));
                    clientThread.Start();
                }
            }
        }
 public void NewClientConnected(MQTTClient client)
 {
     Clients.All.newClientConnected(client);
 }
        private void HandleClient(MQTTClient client)
        {
            var tcpClient = client.TCPClient;
            NetworkStream stream = tcpClient.GetStream();
            while (_runBroker)
            {
                try
                {
                    try
                    {
                        int buffer;
                        if ((buffer = stream.ReadByte()) != -1)
                        {

                            bool disconnect = false;
                            List<byte> bufferList = new List<byte>();
                            do
                            {
                                bufferList.Add((byte) buffer);
                                if (stream.DataAvailable)
                                    buffer = stream.ReadByte();
                                else break;
                            } while (buffer != -1);
                            var response = DoRecieve(client, bufferList, out disconnect);
                            if (disconnect || !_runBroker)
                            {
                                break;
                            }
                            Console.ForegroundColor = ConsoleColor.Green;
                            if (response != null)
                            {
                                var hubContext = GlobalHost.ConnectionManager.GetHubContext<BrokerHub>();
                                client.LastContactTime = DateTime.Now;
                                stream.Write(response.PacketBytes, 0, response.PacketBytes.Length);
                                hubContext.Clients.All.newPacketRecieved(false, client.UniqueId, Enum.GetName(typeof(MQTTPacketTypes), response.PacketType), string.Empty, DateTime.Now.ToLongTimeString());
                                Console.WriteLine(Enum.GetName(typeof(MQTTPacketTypes), response.PacketType)+ " sent");
                                stream.Flush();
                            }
                            Console.ResetColor();
                        }
                    }
                    catch (IOException ex)
                    {
                        // if the ReceiveTimeout is reached an IOException will be raised with ErrorCode 10060
                        var socketException = ex.InnerException as SocketException;
                        if (socketException == null || socketException.ErrorCode != 10060)
                            throw; // if it's not the "expected" exception, let's not hide the error
                        // if it is the receive timeout, then reading ended
                    }
                }
                catch (Exception e)
                {
                    System.Diagnostics.Trace.WriteLine("Error in Broker communication handle mqttClient: " + e.Message);
                    Console.WriteLine("Error in Broker communication handle mqttClient: " + e.Message);
                }
            }
            stream.Close();
            tcpClient.Close();
        }
 public void ClientDisconnected(MQTTClient client)
 {
     Clients.All.clientDisconnected(client);
 }