public WebSocketImplementation(Guid id, bool isClient, Func <MemoryStream> recycledStreamFactory, Stream stream, WebSocketOptions options, Uri requestUri, EndPoint remoteEndPoint, EndPoint localEndPoint, Dictionary <string, string> headers)
        {
            this.ID       = id;
            this.IsClient = isClient;
            this.IncludeExceptionInCloseResponse = options.IncludeExceptionInCloseResponse;
            this.KeepAliveInterval = options.KeepAliveInterval.Ticks < 0 ? TimeSpan.FromSeconds(60) : options.KeepAliveInterval;
            this.RequestUri        = requestUri;
            this.RemoteEndPoint    = remoteEndPoint;
            this.LocalEndPoint     = localEndPoint;
            this.Set("Headers", headers);

            this._recycledStreamFactory = recycledStreamFactory ?? WebSocketHelper.GetRecyclableMemoryStreamFactory();
            this._stream          = stream;
            this._state           = WebSocketState.Open;
            this._subProtocol     = options.SubProtocol;
            this._processingCTS   = new CancellationTokenSource();
            this._pingpongManager = new PingPongManager(this, options, this._processingCTS.Token);
            this._logger          = Logger.CreateLogger <WebSocketImplementation>();
        }
        public WebSocketImplementation(Guid id, bool isClient, Func <MemoryStream> recycledStreamFactory, Stream stream, WebSocketOptions options, Uri requestUri, EndPoint remoteEndPoint, EndPoint localEndPoint)
        {
            if (options.KeepAliveInterval.Ticks < 0)
            {
                throw new ArgumentException("KeepAliveInterval must be Zero or positive", nameof(options));
            }

            this.ID       = id;
            this.IsClient = isClient;
            this.IncludeExceptionInCloseResponse = options.IncludeExceptionInCloseResponse;
            this.KeepAliveInterval = options.KeepAliveInterval;
            this.RequestUri        = requestUri;
            this.RemoteEndPoint    = remoteEndPoint;
            this.LocalEndPoint     = localEndPoint;

            this._recycledStreamFactory = recycledStreamFactory ?? WebSocketHelper.GetRecyclableMemoryStreamFactory();
            this._stream      = stream;
            this._state       = WebSocketState.Open;
            this._subProtocol = options.SubProtocol;
            this._readingCTS  = new CancellationTokenSource();

            if (this.KeepAliveInterval == TimeSpan.Zero)
            {
                Events.Log.KeepAliveIntervalZero(this.ID);
            }
            else
            {
                this._pingpongManager = new PingPongManager(this, this._readingCTS.Token);
            }
        }