Example #1
0
        /// <summary>Accept and process web socket.</summary>
        /// <param name="context">The context.</param>
        /// <param name="client"> The client.</param>
        /// <returns>An asynchronous result.</returns>
        private async Task AcceptAndProcessWebSocket(
            HttpContext context,
            WebsocketClientInformation client)
        {
            // prevent WebSocket errors from bubbling up
            try
            {
                // accept the connection
                using (var webSocket = await context.WebSockets.AcceptWebSocketAsync().ConfigureAwait(false))
                {
                    // register our client
                    WebsocketManager.RegisterClient(client);

                    // create a cancellation token source so we can cancel our read/write tasks
                    CancellationTokenSource processCancelSource = new CancellationTokenSource();

                    // link our local close with the application lifetime close for simplicity
                    CancellationToken cancelToken = CancellationTokenSource.CreateLinkedTokenSource(
                        _applicationStopping,
                        processCancelSource.Token).Token;

                    Task[] webSocketTasks = new Task[2];

                    // create send task
                    webSocketTasks[0] = Task.Run(async() =>
                    {
                        try
                        {
                            await WriteClientMessages(webSocket, client.Uid, cancelToken).ConfigureAwait(false);
                        }
                        finally
                        {
                            // **** cancel read if write task has exited ***
                            processCancelSource.Cancel();
                        }
                    });

                    // create receive task
                    webSocketTasks[1] = Task.Run(async() =>
                    {
                        try
                        {
                            await ReadClientMessages(webSocket, client.Uid, cancelToken).ConfigureAwait(false);
                        }
                        finally
                        {
                            // cancel write if read task has exited
                            processCancelSource.Cancel();
                        }
                    });

                    // start tasks and wait for them to complete
                    await Task.WhenAll(webSocketTasks).ConfigureAwait(false);

                    // close our web socket (do not allow cancel)
                    await webSocket.CloseAsync(
                        WebSocketCloseStatus.EndpointUnavailable,
                        "Connection closing",
                        CancellationToken.None).ConfigureAwait(false);
                }
            }
            catch (WebSocketException wsEx)
            {
                // just log for now
                Console.WriteLine($" <<< caught exception: {wsEx.Message}");
            }
            finally
            {
                WebsocketManager.UnregisterClient(client.Uid);
            }

            return;
        }