Ejemplo n.º 1
0
        // Order of operations:
        // 1. A WebSocket handshake request is received by the middleware.
        // 2. The middleware inserts an alternate Accept signature into the OWIN environment.
        // 3. The middleware invokes Next and stores Next's Task locally. It then returns an alternate Task to the server.
        // 4. The OwinFeatureCollection adapts the alternate Accept signature to IHttpWebSocketFeature.AcceptAsync.
        // 5. A component later in the pipleline invokes IHttpWebSocketFeature.AcceptAsync (mapped to AcceptWebSocketAsync).
        // 6. The middleware calls the OWIN Accept, providing a local callback, and returns an incomplete Task.
        // 7. The middleware completes the alternate Task it returned from Invoke, telling the server that the request pipeline has completed.
        // 8. The server invokes the middleware's callback, which creats a WebSocket adapter complete's the orriginal Accept Task with it.
        // 9. The middleware waits while the application uses the WebSocket, where the end is signaled by the Next's Task completion.
        public static AppFunc AdaptWebSockets(AppFunc next)
        {
            return(environment =>
            {
                object accept;
                if (environment.TryGetValue(OwinConstants.WebSocket.Accept, out accept) && accept is WebSocketAccept)
                {
                    var adapter = new OwinWebSocketAcceptAdapter((WebSocketAccept)accept);

                    environment[OwinConstants.WebSocket.AcceptAlt] = new WebSocketAcceptAlt(adapter.AcceptWebSocketAsync);

                    try
                    {
                        adapter.UpstreamTask = next(environment);
                        adapter.UpstreamWentAsyncTcs.TrySetResult(0);
                        adapter.UpstreamTask.ContinueWith(adapter.EnsureCompleted, TaskContinuationOptions.ExecuteSynchronously);
                    }
                    catch (Exception ex)
                    {
                        adapter.UpstreamWentAsyncTcs.TrySetException(ex);
                        throw;
                    }

                    return adapter.RequestTask;
                }
                else
                {
                    return next(environment);
                }
            });
        }
        // Order of operations:
        // 1. A WebSocket handshake request is received by the middleware.
        // 2. The middleware inserts an alternate Accept signature into the OWIN environment.
        // 3. The middleware invokes Next and stores Next's Task locally. It then returns an alternate Task to the server.
        // 4. The OwinFeatureCollection adapts the alternate Accept signature to IHttpWebSocketFeature.AcceptAsync.
        // 5. A component later in the pipleline invokes IHttpWebSocketFeature.AcceptAsync (mapped to AcceptWebSocketAsync).
        // 6. The middleware calls the OWIN Accept, providing a local callback, and returns an incomplete Task.
        // 7. The middleware completes the alternate Task it returned from Invoke, telling the server that the request pipeline has completed.
        // 8. The server invokes the middleware's callback, which creats a WebSocket adapter complete's the orriginal Accept Task with it.
        // 9. The middleware waits while the application uses the WebSocket, where the end is signaled by the Next's Task completion.
        public static AppFunc AdaptWebSockets(AppFunc next)
        {
            return environment =>
            {
                object accept;
                if (environment.TryGetValue(OwinConstants.WebSocket.Accept, out accept) && accept is WebSocketAccept)
                {
                    var adapter = new OwinWebSocketAcceptAdapter((WebSocketAccept)accept);

                    environment[OwinConstants.WebSocket.AcceptAlt] = new WebSocketAcceptAlt(adapter.AcceptWebSocketAsync);

                    try
                    {
                        adapter.UpstreamTask = next(environment);
                        adapter.UpstreamWentAsyncTcs.TrySetResult(0);
                        adapter.UpstreamTask.ContinueWith(adapter.EnsureCompleted, TaskContinuationOptions.ExecuteSynchronously);
                    }
                    catch (Exception ex)
                    {
                        adapter.UpstreamWentAsyncTcs.TrySetException(ex);
                        throw;
                    }

                    return adapter.RequestTask;
                }
                else
                {
                    return next(environment);
                }
            };
        }