private async void CloseConnection(Frame wsFrame)
        {
            if (wsFrame == null)
            {
                this.State = ConnectionState.Closing;
                if (ConnectionClosing != null)
                {
                    ConnectionClosing(this, wsFrame.TextData);
                }
    
            }
            

            string reason = "Closing the connection";//TODO: Need to give proper reason for connection close
            byte[] payload = Encoding.UTF8.GetBytes(reason);

            await Send(Frame.GetCloseFrame(payload, true));
            if (ConncetionClosed != null)
            {
                ConncetionClosed(this, null);
            }

            try
            {
                if (client.Connected)
                {
                    client.Close();
                }
            }
            catch (Exception ex)
            {

            }
        }
        public static bool TryParse(byte[] rawData, int length, out Frame frame)
        {
            frame = null;
            if (length < 2)
            {
                return false;
            }
            bool finBit = (rawData[0] & (1 << 7)) != 0;
            var opCode = rawData[0] & 0x0F;
            long payLoadLen = rawData[1] & 0x7F;
            DataType dataType = DataType.binary;
            string textData = string.Empty;
            byte[] binData = null;

            bool isMasked = (rawData[1] & (1 << 7)) != 0;
            int headerOffSet = 2;

            if (payLoadLen == 126)
            {
                if (length < 4)
                {
                    return false;
                }
                var newPayloadLen = BitConverter.ToInt16(rawData, 2);
                payLoadLen = newPayloadLen;
                headerOffSet = 4;
            }
            else if (payLoadLen == 127)
            {
                if (length < 10)
                {
                    return false;
                }
                payLoadLen = BitConverter.ToInt64(rawData, 2);
                headerOffSet = 10;
            }
            byte[] maskKey = new byte[4];
            if (isMasked)
            {
                Array.Copy(rawData, headerOffSet, maskKey, 0, 4);
                headerOffSet += 4;
            }

            if ((length - headerOffSet) < payLoadLen)
            {
                return false;
            }

            //If we reached this far, we can parse the frame
            byte[] data = new byte[payLoadLen];
            byte[] unmaskedData = null;
            Array.Copy(rawData, headerOffSet, data, 0, payLoadLen);

            if (isMasked)
            {
                unmaskedData = new byte[payLoadLen];
                for (int i = 0; i < data.Length; i++)
                {
                    unmaskedData[i] = (byte)(data[i] ^ maskKey[i % 4]);
                }
            }

            if (opCode == 1)
            {
                dataType = DataType.text;
                textData = isMasked ? Encoding.UTF8.GetString(unmaskedData) : Encoding.UTF8.GetString(data);
            }
            else if (opCode == 2)
            {
                dataType = DataType.binary;
                binData = isMasked ? unmaskedData : data;
            }

            frame = new Frame(finBit, opCode, dataType, textData, binData);

            return true;
        }
 private void ProcessFrame(Frame wsFrame)
 {
     if (wsFrame == null)
     {
         return;
     }
     switch (wsFrame.OPCode)
     {
         case OpCodes.TEXT_FRAME:
             if (DataReceived != null)
             {
                 DataReceived(this, new Message(DataType.text, wsFrame.TextData));
             }
             break;
         case OpCodes.BINARY_FRAME:
             if (DataReceived != null)
             {
                 DataReceived(this, new Message(DataType.binary, null, wsFrame.BinaryData));
             }
             break;
         case OpCodes.PING:
             SendPongMessage();
             break;
         case OpCodes.PONG:
             break;
         case OpCodes.CONNECTION_CLOSE:
             CloseConnection(wsFrame);
             break;
         case OpCodes.CONTINUATION_FRAME:
             break;
     }
 }