private async Task ListenClient(WebSocketUser user)
        {
            using (Stream ns = user.Stream) {
                WebSocketReader reader = new WebSocketReader();
                var             res    = await InterpretHeader(user, ns);

                if (!(res.Item1))
                {
                    RemoveClient(user, WebSocketDisconnection.NoHeader);
                    return;
                }

                Logger.DebugWrite("INFO", $"Socket successfully handshaked the update. UID: {user.UID}");
                OnHandshake?.Invoke(this, new HandshakeEventArgs(user, res.Item2));

                while (Running && !user.ListenToken.IsCancellationRequested)
                {
                    WebSocketFrame frame = await reader.Read(ns, user);

                    if (frame == null || frame.Opcode == WebSocketOpcode.ConnectionCloseFrame)
                    {
                        RemoveClient(user, WebSocketDisconnection.Disconnect);
                        break;
                    }

                    switch (frame.Opcode)
                    {
                    case WebSocketOpcode.PingFrame:

                        if (frame.Data.Length <= 125)
                        {
                            await user.Writer.WritePong(frame);

                            OnPing?.Invoke(this, new PingEventArgs(frame.Data));
                        }

                        break;

                    case WebSocketOpcode.PongFrame:

                        OnPong?.Invoke(this, new PongEventArgs(frame.Data));

                        break;

                    case WebSocketOpcode.BinaryFrame:

                        user.Meta.LastTime.Binary = DateTime.UtcNow;

                        if (RttEnabled && frame.Data.Length == 4 && frame.Data[0] == 26 &&
                            frame.Data[1] == 27 && frame.Data[2] == 28 && frame.Data[3] == 29)
                        {
                            OnPongReceived(user);
                        }

                        OnMessage?.Invoke(this, new MessageEventArgs(user, frame));

                        break;

                    case WebSocketOpcode.TextFrame:

                        user.Meta.LastTime.Text = DateTime.UtcNow;

                        OnMessage?.Invoke(this, new MessageEventArgs(user, frame));

                        break;
                    }
                }
            }
        }
 public async Task WritePong(WebSocketFrame ping)
 {
     await Write(WebSocketOpcode.PongFrame, ping.Data);
 }
        public async Task <WebSocketFrame> Read(Stream stream, WebSocketUser user)
        {
            byte first;

            try {
                byte[] firstData = new byte[1];
                await stream.ReadAsync(firstData, 0, firstData.Length);

                first = firstData[0];
            } catch (Exception) {
                return(null);
            }

            //if (user != null && !WebSocketUtils.IsClientConnected(user)) {

            //    return null;

            //}

            try {
                byte bitFinFlag = 0x80;
                byte opcodeFlag = 0x0F;

                bool            bitFinSet = (first & bitFinFlag) == bitFinFlag;
                WebSocketOpcode opcode    = (WebSocketOpcode)(first & opcodeFlag);

                byte bitMaskFlag = 0x80;

                byte[] secData = new byte[1];
                await stream.ReadAsync(secData, 0, secData.Length);

                byte second = secData[0];

                bool  bitMaskSet = (second & bitMaskFlag) == bitMaskFlag;
                ulong length     = await ReadLength(stream, second);

                if (length != 0)
                {
                    byte[] decoded;

                    if (bitMaskSet)
                    {
                        byte[] key = await WebSocketReaderWriter.Read(stream, 4);

                        byte[] encoded = await WebSocketReaderWriter.Read(stream, length);

                        decoded = new byte[length];

                        for (int i = 0; i < encoded.Length; i++)
                        {
                            decoded[i] = (byte)(encoded[i] ^ key[i % 4]);
                        }
                    }
                    else
                    {
                        decoded = await WebSocketReaderWriter.Read(stream, length);
                    }

                    WebSocketFrame frame = new WebSocketFrame(opcode, decoded);

                    return(frame);
                }
            }
            catch (Exception er) {
                Logger.DebugWrite("FAILED", "Error read bytes: ", er);
                return(null);
            }

            return(null);
        }