public async Task Start()
        {
            var webSocket = this.Context.WebSocket;
            ArraySegment <byte> receiveBuffer = _bufferManager.BorrowBuffer();
            ArraySegment <byte> sessionBuffer = _bufferManager.BorrowBuffer();
            int sessionBufferCount            = 0;

            _log.DebugFormat("Session started for [{0}] on [{1}] in module [{2}] with session count [{3}].",
                             this.RemoteEndPoint,
                             this.StartTime.ToString(@"yyyy-MM-dd HH:mm:ss.fffffff"),
                             this.Module.ModuleName,
                             this.Module.SessionCount);
            try
            {
                while (webSocket.State == WebSocketState.Open)
                {
                    this.CancellationToken.ThrowIfCancellationRequested();

                    var receiveResult = await webSocket.ReceiveAsync(receiveBuffer, this.CancellationToken);

                    switch (receiveResult.MessageType)
                    {
                    case WebSocketMessageType.Text:
                    {
                        if (receiveResult.EndOfMessage && sessionBufferCount == 0)
                        {
                            var message = new WebSocketTextMessage(this, this.Encoding.GetString(receiveBuffer.Array, receiveBuffer.Offset, receiveResult.Count));
                            await this.Module.ReceiveTextMessage(message);
                        }
                        else
                        {
                            SegmentBufferDeflector.AppendBuffer(_bufferManager, ref receiveBuffer, receiveResult.Count, ref sessionBuffer, ref sessionBufferCount);

                            if (receiveResult.EndOfMessage)
                            {
                                var message = new WebSocketTextMessage(this, this.Encoding.GetString(sessionBuffer.Array, sessionBuffer.Offset, sessionBufferCount));
                                await this.Module.ReceiveTextMessage(message);

                                sessionBufferCount = 0;
                            }
                        }
                    }
                    break;

                    case WebSocketMessageType.Binary:
                    {
                        if (receiveResult.EndOfMessage && sessionBufferCount == 0)
                        {
                            var message = new WebSocketBinaryMessage(this, receiveBuffer.Array, receiveBuffer.Offset, receiveResult.Count);
                            await this.Module.ReceiveBinaryMessage(message);
                        }
                        else
                        {
                            SegmentBufferDeflector.AppendBuffer(_bufferManager, ref receiveBuffer, receiveResult.Count, ref sessionBuffer, ref sessionBufferCount);

                            if (receiveResult.EndOfMessage)
                            {
                                var message = new WebSocketBinaryMessage(this, sessionBuffer.Array, sessionBuffer.Offset, sessionBufferCount);
                                await this.Module.ReceiveBinaryMessage(message);

                                sessionBufferCount = 0;
                            }
                        }
                    }
                    break;

                    case WebSocketMessageType.Close:
                    {
                        await Close(
                            receiveResult.CloseStatus.HasValue?receiveResult.CloseStatus.Value : WebSocketCloseStatus.NormalClosure,
                            receiveResult.CloseStatusDescription);
                    }
                    break;
                    }
                }
            }
            catch (WebSocketException) { }
            finally
            {
                _bufferManager.ReturnBuffer(receiveBuffer);
                _bufferManager.ReturnBuffer(sessionBuffer);

                _log.DebugFormat("Session closed for [{0}] on [{1}] in module [{2}] with session count [{3}].",
                                 this.RemoteEndPoint,
                                 DateTime.UtcNow.ToString(@"yyyy-MM-dd HH:mm:ss.fffffff"),
                                 this.Module.ModuleName,
                                 this.Module.SessionCount - 1);

                if (webSocket != null)
                {
                    webSocket.Dispose();
                }
            }
        }
 public abstract Task ReceiveBinaryMessage(WebSocketBinaryMessage message);