public override Task ExecuteResultAsync(ActionContext context)
        {
            var webSocket = context.HttpContext.WebSockets.AcceptWebSocketAsync().Result;

            BlockingStream stream = new BlockingStream(16);

            //Read from stream as it comes in.
            Task.Factory.StartNew(() => _streamHandlerAction(stream));

            var receive = Task.Factory.StartNew(() =>
            {
                byte[] buffer = new byte[1024 * 63];

                while (true)
                {
                    // MUST read if we want the state to get updated...
                    var result = webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None).Result;

                    stream.Write(buffer, 0, result.Count);

                    if (result.MessageType == WebSocketMessageType.Close)
                    {
                        webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, String.Empty, CancellationToken.None);
                        stream.CompleteWriting();
                        break;
                    }
                }

            });
            return receive;
        }
        protected override async Task HandleWebSocket(WebSocketContext context, bool closeConnection = true)
        {
            if (context == null)
                throw new ApplicationException("Could not determine websocket context.");

            BlockingStream stream = new BlockingStream(16);

            var ws = context.WebSocket;

            new Task(async () =>
            {
                byte[] buffer = new byte[1024 * 64];

                while (true)
                {
                    // MUST read if we want the state to get updated...
                    var result = await ws.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);

                    stream.Write(buffer, 0, result.Count);

                    if (result.MessageType == WebSocketMessageType.Close)
                    {
                        if (closeConnection)
                            await ws.CloseAsync(WebSocketCloseStatus.NormalClosure, String.Empty, CancellationToken.None);
                        stream.CompleteWriting();
                        break;
                    }
                }
            }).Start();

            StreamHandlerAction(stream);
        }
        public void BlockingStream()
        {
            Random random = new Random();

            byte[] randomBytes = new byte[1024 * 1024];
            random.NextBytes(randomBytes);
            using (BlockingStream stream = new BlockingStream(16))
            {
                var producer = Task.Factory.StartNew(() =>
                {
                    byte[] buffer = new byte[16 * 1024];//ChunkSize
                    for (int i = 0; i < randomBytes.Length / buffer.Length; i++)
                    {
                        Buffer.BlockCopy(randomBytes, i * buffer.Length, buffer, 0, buffer.Length);
                        stream.Write(buffer, 0, buffer.Length);
                    }
                    stream.CompleteWriting();
                });

                byte[] readBuffer = new byte[3 * 1024];
                using (MemoryStream actualStream = new MemoryStream())
                {
                    int read = 0;
                    while ((read = stream.Read(readBuffer, 0, readBuffer.Length)) > 0)
                    {
                        actualStream.Write(readBuffer, 0, read);
                    }

                    Assert.True(randomBytes.SequenceEqual(actualStream.ToArray()));
                }

                Task.WaitAll(producer);
            }
        }