Araqne.Web.WebSocket.ReadCallback C# (CSharp) Method

ReadCallback() private method

private ReadCallback ( IAsyncResult result ) : void
result IAsyncResult
return void
        private void ReadCallback(IAsyncResult result)
        {
            if (closed)
                return;

            try
            {
                int readBytes = client.GetStream().EndRead(result);

                ReadContext ctx = result.AsyncState as ReadContext;

                if (ctx.stage == ReadStage.Header)
                {
                    int payloadLen = ctx.headerBuffer[1] & 0x7f;
                    ctx.headerReadBytes += readBytes;
                    if (ctx.headerReadBytes >= 2)
                    {
                        if (payloadLen < 126)
                        {
                            ctx.stage = ReadStage.Payload;
                            ctx.payloadReadBytes = 0;
                            ctx.expected = 2 + payloadLen;
                        }
                        else
                        {
                            ctx.stage = ReadStage.ExtendedHeader;
                            ctx.expected = payloadLen == 126 ? 4 : 10;
                        }
                    }
                }
                else if (ctx.stage == ReadStage.ExtendedHeader)
                {
                    int payloadLen = ctx.headerBuffer[1] & 0x7f;
                    ctx.headerReadBytes += readBytes;
                    byte[] h = ctx.headerBuffer;
                    if (payloadLen == 126 && ctx.headerReadBytes == 4)
                    {
                        int l = (h[2] << 8 | h[3]) & 0xffff;
                        ctx.payloadReadBytes = 0;
                        ctx.payloadBuffer = new byte[l];
                        ctx.expected = l;
                        ctx.stage = ReadStage.Payload;
                    }
                    else if (payloadLen == 127 && ctx.headerReadBytes == 10)
                    {
                        byte[] b = new byte[8];
                        Array.Copy(h, 2, b, 0, 8);
                        Array.Reverse(b);
                        long l = BitConverter.ToInt64(b, 0);
                        ctx.payloadBuffer = new byte[l];
                        ctx.expected = (int)l;
                        ctx.stage = ReadStage.Payload;
                    }
                }
                else if (ctx.stage == ReadStage.Payload)
                {
                    ctx.payloadReadBytes += readBytes;
                    if (ctx.payloadReadBytes == ctx.expected)
                    {
                        byte[] h = ctx.headerBuffer;
                        byte[] p = ctx.payloadBuffer;

                        bool fin = (h[0] & 0x80) == 0x80;
                        Opcode opcode = (Opcode)(h[0] & 0xf);

                        if (opcode == Opcode.Text)
                        {
                            ctx.fragments.Add(p);

                            if (fin)
                            {
                                string json = BuildText(ctx);
                                if (OnMessage != null)
                                    OnMessage(new WebSocketMessage((int)opcode, json));
                            }
                        }

                        // clear and ready for next frame
                        ctx.headerReadBytes = 0;
                        ctx.payloadReadBytes = 0;
                        ctx.payloadBuffer = null;
                        ctx.expected = 2;
                        ctx.fragments.Clear();
                        ctx.stage = ReadStage.Header;
                    }
                }

                if (ctx.stage == ReadStage.Payload)
                {
                    int next = (ctx.expected - ctx.payloadReadBytes);
                    if (next == 0)
                    {
                        int i = 0;
                    }
                    client.GetStream().BeginRead(ctx.payloadBuffer, ctx.payloadReadBytes, ctx.expected - ctx.payloadReadBytes, new AsyncCallback(ReadCallback), ctx);
                }
                else
                {
                    int next = (ctx.expected - ctx.headerReadBytes);
                    client.GetStream().BeginRead(ctx.headerBuffer, ctx.headerReadBytes, ctx.expected - ctx.headerReadBytes, new AsyncCallback(ReadCallback), ctx);
                }
            }
            catch (Exception e)
            {
                if (OnError != null)
                    OnError(e);

                Close(e);
            }
        }