public async Task ReceiveMessageAsync()

in ClearScript/Util/Web/WebSocket.cs [44:160]


        public async Task<Message> ReceiveMessageAsync()
        {
            using (await receiveSemaphore.CreateLockScopeAsync().ConfigureAwait(false))
            {
                bool? isBinary = null;
                var payloads = new List<byte[]>();

                while (true)
                {
                    var frame = await ReceiveFrameAsync().ConfigureAwait(false);

                    if (frame.OpCode == OpCodes.Text)
                    {
                        if (isBinary.HasValue)
                        {
                            throw new Exception(ErrorCode.ProtocolError, "Received unexpected text frame from WebSocket");
                        }

                        isBinary = false;

                        payloads.Add(frame.Payload);
                        if (frame.Final)
                        {
                            break;
                        }
                    }
                    else if (frame.OpCode == OpCodes.Binary)
                    {
                        if (isBinary.HasValue)
                        {
                            throw new Exception(ErrorCode.ProtocolError, "Received unexpected binary frame from WebSocket");
                        }

                        isBinary = true;

                        payloads.Add(frame.Payload);
                        if (frame.Final)
                        {
                            break;
                        }
                    }
                    else if (frame.OpCode == OpCodes.Continuation)
                    {
                        if (!isBinary.HasValue)
                        {
                            throw new Exception(ErrorCode.ProtocolError, "Received unexpected continuation frame from WebSocket");
                        }

                        payloads.Add(frame.Payload);
                        if (frame.Final)
                        {
                            break;
                        }
                    }
                    else if (frame.OpCode == OpCodes.Ping)
                    {
                        var response = new Frame { Final = true, OpCode = OpCodes.Pong, Payload = frame.Payload };
                        await SendFrameAsync(response).ConfigureAwait(false);
                    }
                    else if (frame.OpCode == OpCodes.Pong)
                    {
                    }
                    else if (frame.OpCode == OpCodes.Close)
                    {
                        var errorCode = ErrorCode.NormalClosure;
                        var message = "The WebSocket was closed by the remote endpoint";

                        if (frame.Payload.Length >= 2)
                        {
                            errorCode = (ErrorCode)frame.Payload.ToHostUInt16();
                            if (frame.Payload.Length > 2)
                            {
                                message = Encoding.UTF8.GetString(frame.Payload, 2, frame.Payload.Length - 2);
                            }
                        }

                        throw new Exception(errorCode, message);
                    }
                    else
                    {
                        throw new Exception(ErrorCode.ProtocolError, "Received unrecognized frame from WebSocket");
                    }
                }

                var length = 0L;

                var overflow = false;
                try
                {
                    length = payloads.Aggregate(0L, (tempLength, segment) => checked(tempLength + segment.LongLength));
                }
                catch (OverflowException)
                {
                    overflow = true;
                }

                const long maxLength = 64 * 1024 * 1024;
                if (overflow || (length > maxLength))
                {
                    throw new Exception(ErrorCode.MessageTooBig, "Incoming WebSocket message payload is too large");
                }

                var fullPayload = new byte[length];

                var index = 0L;
                foreach (var payload in payloads)
                {
                    Array.Copy(payload, 0L, fullPayload, index, payload.LongLength);
                    index += payload.LongLength;
                }

                // ReSharper disable once ConditionIsAlwaysTrueOrFalse
                Debug.Assert(isBinary.HasValue);

                return new Message { IsBinary = isBinary.Value, Payload = fullPayload };
            }
        }