Inheritance: WebSocketHandler, IWebSocket
Beispiel #1
0
        public Task ProcessRequestAsync(IDictionary<string, object> env)
        {
            object value;
            WebSocket webSocket;

            // Try to get the websocket context from the environment
            if (!env.TryGetValue(typeof(WebSocketContext).FullName, out value))
            {
                webSocket = new OwinWebSocket(env);
            }
            else
            {
                webSocket = ((WebSocketContext)value).WebSocket;
            }

            var handler = new DefaultWebSocketHandler();
            var task = handler.ProcessWebSocketRequestAsync(webSocket);

            _callback(handler).Catch()
                              .ContinueWith(t => handler.End());
            return task;
        }
        private void RunWebSocketHandler(DefaultWebSocketHandler handler, CancellationTokenSource cts)
        {
            // async void methods are not supported in ASP.NET and they throw a InvalidOperationException.
            Task.Run(async () =>
            {
                try
                {
                    await _callback(handler);
                }
                catch
                {
                    // This error was already handled by other layers
                    // we can no-op here so we don't cause an unobserved exception
                }

                // Always try to close async, if the websocket already closed
                // then this will no-op
                await handler.CloseAsync();

                // Cancel the token
                cts.Cancel();
            });
        }
        public Task ProcessRequest(IDictionary<string, object> environment)
        {
            object value;
            WebSocket webSocket;

            // Try to get the websocket context from the environment
            if (!environment.TryGetValue(typeof(WebSocketContext).FullName, out value))
            {
                webSocket = new OwinWebSocket(environment);
            }
            else
            {
                webSocket = ((WebSocketContext)value).WebSocket;
            }

            var cts = new CancellationTokenSource();
            var webSocketHandler = new DefaultWebSocketHandler(_maxIncomingMessageSize);
            var task = webSocketHandler.ProcessWebSocketRequestAsync(webSocket, cts.Token);

            RunWebSocketHandler(webSocketHandler, cts);

            return task;
        }
        public async Task DefaultWebSocketHandlerOperationsNoopAfterClose()
        {
            var handler = new DefaultWebSocketHandler(maxIncomingMessageSize: null, 
                                                      logger: new Mock<ILogger>().Object);

            var initialWebSocket = new Mock<WebSocket>();

            initialWebSocket.Setup(w => w.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, "", CancellationToken.None))
                .Returns(TaskAsyncHelper.Empty);

            initialWebSocket.Setup(w => w.CloseAsync(WebSocketCloseStatus.NormalClosure, "", CancellationToken.None))
                .Returns(TaskAsyncHelper.Empty);

            initialWebSocket.Setup(w => w.ReceiveAsync(It.IsAny<ArraySegment<byte>>(), CancellationToken.None))
                     .Returns(Task.FromResult(new WebSocketReceiveResult(0, WebSocketMessageType.Close, endOfMessage: true)));

            await handler.ProcessWebSocketRequestAsync(initialWebSocket.Object, CancellationToken.None);
            
            // Swap the socket here so we can verify what happens after the task returns
            var afterWebSocket = new Mock<WebSocket>();
            
            handler.WebSocket = afterWebSocket.Object;

            await handler.Send(new ArraySegment<byte>(Encoding.UTF8.GetBytes("Hello World")));
            await handler.CloseAsync();

            afterWebSocket.Verify(m => m.State, Times.Never());
            afterWebSocket.Verify(m => m.SendAsync(It.IsAny<ArraySegment<byte>>(), WebSocketMessageType.Text, true, CancellationToken.None), Times.Never());
            afterWebSocket.Verify(m => m.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, "", CancellationToken.None), Times.Never());
        }
        private async Task AcceptWebSocketRequest(ITransportConnection connection)
        {
            var handler = new DefaultWebSocketHandler(_maxIncomingMessageSize, Logger);

            // Configure event handlers before calling ProcessWebSocketRequestAsync
            _socket = handler;
            _socket.OnClose = _closed;
            _socket.OnMessage = _message;
            _socket.OnError = _error;

            WebSocket webSocket;

            try
            {
                webSocket = await Context.AcceptWebSocketAsync();
            }
            catch
            {
                // Bad Request
                _context.Response.StatusCode = 400;
                await _context.Response.WriteAsync(Resources.Error_NotWebSocketRequest);
                return;
            }

            // Start the websocket handler so that we can process things over the channel
            var webSocketHandlerTask = handler.ProcessWebSocketRequestAsync(webSocket, CancellationToken);

            // This needs to come after wiring up the websocket handler
            var ignoredTask = ProcessRequestCore(connection)
                .ContinueWith(async (_, state) =>
            {
                await ((DefaultWebSocketHandler)state).CloseAsync();
            },
            handler);

            await webSocketHandlerTask;
        }