public async Task Invoke(IDictionary <string, object> env)
        {
            var accept = env.TryGetValue("websocket.Accept", out var wsa) ? (WebSocketAccept)wsa : null;

            if (accept != null && (_options.ConnectionEvaluator?.Invoke(env) ?? true))
            {
                env.TryGetValue("owin.RequestPath", out var oPath);
                var path          = (string)oPath;
                var wsProtocolOpt = env.TryGetValue("owin.RequestHeaders", out var headers) ?
                                    ((IDictionary <string, string[]>)headers).TryGetValue("Sec-WebSocket-Protocol", out var secWsProtocol) ?
                                    secWsProtocol?[0]?.Split(',')?.FirstOrDefault()?.Trim() : null : null;
                Dictionary <string, object> acceptOptions = new Dictionary <string, object>();
                if (wsProtocolOpt != null)
                {
                    acceptOptions["websocket.SubProtocol"] = wsProtocolOpt;
                }

                var ctx = new OwinRequestContext(env);
                accept(acceptOptions, (ws) => AcceptSocketAsync(ctx, ws));
                env["owin.ResponseStatusCode"] = (int)HttpStatusCode.SwitchingProtocols;
            }
            else
            {
                await _next(env);
            }
        }
 private async Task AcceptSocketAsync(OwinRequestContext ctx, IDictionary <string, object> ws)
 {
     if (!_options.ForceOwinWebsockets && ws.TryGetValue("System.Net.WebSockets.WebSocketContext", out var _wsctx))
     {
         WebSocketContext wsctx = (WebSocketContext)_wsctx;
         await WebsocketConnector.HandleWebsocketAsync(ctx, wsctx.WebSocket, _options);
     }
     else
     {
         var wrapper = new OwinWebsocketWrapper(ws);
         await WebsocketConnector.HandleWebsocketAsync(ctx, wrapper, _options);
     }
 }