public void DoRequestListening()
        {
            using (EneterTrace.Entering())
            {
                myIsListeningToResponses = true;
                ushort aCloseCode = 0;

                try
                {
                    DynamicStream aContinuousMessageStream = null;

                    while (!myStopReceivingRequestedFlag)
                    {
                        // Decode the incoming message.
                        WebSocketFrame aFrame = WebSocketFormatter.DecodeFrame(myClientStream);

                        if (!myStopReceivingRequestedFlag && aFrame != null)
                        {
                            // Frames from server must be unmasked.
                            // According the protocol, If the frame was NOT masked, the server must close connection with the client.
                            if (aFrame.MaskFlag == false)
                            {
                                throw new InvalidOperationException(TracedObject + "received unmasked frame from the client. Frames from client shall be masked.");
                            }

                            // Process the frame.
                            if (aFrame.FrameType == EFrameType.Ping)
                            {
                                // Response 'pong'. The response responses same data as received in the 'ping'.
                                SendFrame(maskingKey => WebSocketFormatter.EncodePongFrame(maskingKey, aFrame.Message));
                            }
                            else if (aFrame.FrameType == EFrameType.Close)
                            {
                                EneterTrace.Debug(TracedObject + "received the close frame.");
                                break;
                            }
                            else if (aFrame.FrameType == EFrameType.Pong)
                            {
                                Notify(PongReceived);
                            }
                            // If a new message starts.
                            else if (aFrame.FrameType == EFrameType.Binary || aFrame.FrameType == EFrameType.Text)
                            {
                                // If a previous message is not finished then the new message is not expected -> protocol error.
                                if (aContinuousMessageStream != null)
                                {
                                    EneterTrace.Warning(TracedObject + "detected unexpected new message. (previous message was not finished)");

                                    // Protocol error close code.
                                    aCloseCode = 1002;
                                    break;
                                }

                                WebSocketMessage aReceivedMessage = null;

                                // If the message does not come in multiple frames then optimize the performance
                                // and use MemoryStream instead of DynamicStream.
                                if (aFrame.IsFinal)
                                {
                                    MemoryStream aMessageStream = new MemoryStream(aFrame.Message);
                                    aReceivedMessage = new WebSocketMessage(aFrame.FrameType == EFrameType.Text, aMessageStream);
                                }
                                else
                                // if the message is split to several frames then use DynamicStream so that writing of incoming
                                // frames and reading of already received data can run in parallel.
                                {
                                    // Create stream where the message data will be writen.
                                    aContinuousMessageStream = new DynamicStream();
                                    aContinuousMessageStream.WriteWithoutCopying(aFrame.Message, 0, aFrame.Message.Length);
                                    aReceivedMessage = new WebSocketMessage(aFrame.FrameType == EFrameType.Text, aContinuousMessageStream);
                                }

                                // Put received message to the queue.
                                myReceivedMessages.EnqueueMessage(aReceivedMessage);
                            }
                            // If a message continues. (I.e. message is split into more fragments.)
                            else if (aFrame.FrameType == EFrameType.Continuation)
                            {
                                // If the message does not exist then continuing frame does not have any sense -> protocol error.
                                if (aContinuousMessageStream == null)
                                {
                                    EneterTrace.Warning(TracedObject + "detected unexpected continuing of a message. (none message was started before)");

                                    // Protocol error close code.
                                    aCloseCode = 1002;
                                    break;
                                }

                                aContinuousMessageStream.WriteWithoutCopying(aFrame.Message, 0, aFrame.Message.Length);

                                // If this is the final frame.
                                if (aFrame.IsFinal)
                                {
                                    aContinuousMessageStream.IsBlockingMode = false;
                                    aContinuousMessageStream = null;
                                }
                            }
                        }

                        // If disconnected
                        if (aFrame == null)// || !myTcpClient.Client.Poll(0, SelectMode.SelectWrite))
                        {
                            //EneterTrace.Warning(TracedObject + "detected the TCP connection is not available. The connection will be closed.");
                            break;
                        }
                    }
                }
                catch (IOException)
                {
                    // Ignore this exception. It is often thrown when the connection was closed.
                    // Do not thrace this because the tracing degradates the performance in this case.
                }
                catch (Exception err)
                {
                    EneterTrace.Error(TracedObject + ErrorHandler.FailedInListeningLoop, err);
                }

                // If the connection is being closed due to a protocol error.
                if (aCloseCode > 1000)
                {
                    // Try to send the close message.
                    try
                    {
                        byte[] aCloseMessage = WebSocketFormatter.EncodeCloseFrame(null, aCloseCode);
                        myClientStream.Write(aCloseMessage, 0, aCloseMessage.Length);
                    }
                    catch
                    {
                    }
                }

                myIsListeningToResponses = false;

                myReceivedMessages.UnblockProcessingThreads();

                // Notify the listening to messages stoped.
                Notify(ConnectionClosed);
            }
        }
        public static WebSocketFrame DecodeFrame(Stream inputStream)
        {
            using (EneterTrace.Entering())
            {
                try
                {
                    // Note: Do not enclose the BinaryReader with using because it will close the stream!!!
                    BinaryReader aReader = new BinaryReader(inputStream);

                    // Read the first 2 bytes.
                    byte[] aFirst2Bytes = aReader.ReadBytes(2);
                    if (aFirst2Bytes.Length < 2)
                    {
                        throw new EndOfStreamException("End of stream during reading first two bytes of web socket frame.");
                    }

                    // Get if final.
                    bool anIsFinal = (aFirst2Bytes[0] & 0x80) != 0;

                    // Get opcode.
                    EFrameType aFrameType = (EFrameType)(aFirst2Bytes[0] & 0xF);

                    // Get if masked.
                    bool anIsMasked = (aFirst2Bytes[1] & 0x80) != 0;

                    // Get the message length.
                    int aMessageLength = aFirst2Bytes[1] & 0x7F;
                    if (aMessageLength == 126)
                    {
                        // The length is encoded in next 2 bytes (16 bits).
                        ushort aLength = aReader.ReadUInt16();

                        // Websockets are in big endians, so convert it to little endian.
                        aMessageLength = ConvertEndian(aLength);
                    }
                    else
                    if (aMessageLength == 127)
                    {
                        // The length is encoded in next 8 bytes (64 bits).
                        ulong aLength = aReader.ReadUInt64();

                        // Websockets are in big endians, so convert it to little endian.
                        aLength = ConvertEndian(aLength);

                        aMessageLength = (int)aLength;
                    }

                    // Get mask bytes.
                    byte[] aMaskBytes = null;
                    if (anIsMasked)
                    {
                        aMaskBytes = aReader.ReadBytes(4);

                        if (aMaskBytes.Length < 4)
                        {
                            throw new EndOfStreamException("End of stream during reading web socket mask bytes.");
                        }
                    }

                    // Get the message data.
                    byte[] aMessageData = aReader.ReadBytes(aMessageLength);
                    if (aMessageData.Length < aMessageLength)
                    {
                        throw new EndOfStreamException("End of stream during reading message data from the web socket frame.");
                    }

                    // If mask was used then unmask data.
                    if (anIsMasked)
                    {
                        for (int i = 0; i < aMessageData.Length; ++i)
                        {
                            aMessageData[i] = (byte)(aMessageData[i] ^ aMaskBytes[i % 4]);
                        }
                    }

                    WebSocketFrame aFrame = new WebSocketFrame(aFrameType, anIsMasked, aMessageData, anIsFinal);

                    return(aFrame);
                }
                catch (EndOfStreamException)
                {
                    // End of the stream.
                    return(null);
                }
                catch (ObjectDisposedException)
                {
                    // End of the stream.
                    return(null);
                }
            }
        }