private async void Start_Click(object sender, RoutedEventArgs e)
        {
            // Have we connected yet?
            if (streamWebSocket != null)
            {
                rootPage.NotifyUser("Already connected", NotifyType.StatusMessage);
                return;
            }

            // Validating the URI is required since it was received from an untrusted source (user input).
            // The URI is validated by calling TryGetUri() that will return 'false' for strings that are not
            // valid WebSocket URIs.
            // Note that when enabling the text box users may provide URIs to machines on the intrAnet
            // or intErnet. In these cases the app requires the "Home or Work Networking" or
            // "Internet (Client)" capability respectively.
            Uri server;
            if (!rootPage.TryGetUri(ServerAddressField.Text, out server))
            {
                return;
            }

            try
            {
                rootPage.NotifyUser("Connecting to: " + server, NotifyType.StatusMessage);

                streamWebSocket = new StreamWebSocket();

                // Dispatch close event on UI thread. This allows us to avoid synchronizing access to streamWebSocket.
                streamWebSocket.Closed += async (senderSocket, args) =>
                {
                    await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => Closed(senderSocket, args));
                };

                await streamWebSocket.ConnectAsync(server);

                readBuffer = new byte[1000];

                // Start a background task to continuously read for incoming data
                Task receiving = Task.Factory.StartNew(Scenario2ReceiveData,
                    streamWebSocket.InputStream.AsStreamForRead(), TaskCreationOptions.LongRunning);

                // Start a background task to continuously write outgoing data
                Task sending = Task.Factory.StartNew(Scenario2SendData,
                    streamWebSocket.OutputStream, TaskCreationOptions.LongRunning);

                rootPage.NotifyUser("Connected", NotifyType.StatusMessage);
            }
            catch (Exception ex) // For debugging
            {
                if (streamWebSocket != null)
                {
                    streamWebSocket.Dispose();
                    streamWebSocket = null;
                }

                WebErrorStatus status = WebSocketError.GetStatus(ex.GetBaseException().HResult);

                switch (status)
                {
                    case WebErrorStatus.CannotConnect:
                    case WebErrorStatus.NotFound:
                    case WebErrorStatus.RequestTimeout:
                        rootPage.NotifyUser("Cannot connect to the server. Please make sure " +
                            "to run the server setup script before running the sample.", NotifyType.ErrorMessage);
                        break;

                    case WebErrorStatus.Unknown:
                        throw;

                    default:
                        rootPage.NotifyUser("Error: " + status, NotifyType.ErrorMessage);
                        break;
                }

                OutputField.Text += ex.Message + "\r\n";
            }
        }
        private async Task StartAsync()
        {
            // Validating the URI is required since it was received from an untrusted source (user input).
            // The URI is validated by calling TryGetUri() that will return 'false' for strings that are not
            // valid WebSocket URIs.
            // Note that when enabling the text box users may provide URIs to machines on the intrAnet
            // or intErnet. In these cases the app requires the "Home or Work Networking" or
            // "Internet (Client)" capability respectively.
            Uri server = rootPage.TryGetUri(ServerAddressField.Text);
            if (server == null)
            {
                return;
            }

            streamWebSocket = new StreamWebSocket();
            streamWebSocket.Closed += OnClosed;

            // If we are connecting to wss:// endpoint, by default, the OS performs validation of
            // the server certificate based on well-known trusted CAs. We can perform additional custom
            // validation if needed.
            if (SecureWebSocketCheckBox.IsChecked == true)
            {
                // WARNING: Only test applications should ignore SSL errors.
                // In real applications, ignoring server certificate errors can lead to Man-In-The-Middle
                // attacks. (Although the connection is secure, the server is not authenticated.)
                // Note that not all certificate validation errors can be ignored.
                // In this case, we are ignoring these errors since the certificate assigned to the localhost
                // URI is self-signed and has subject name = fabrikam.com
                streamWebSocket.Control.IgnorableServerCertificateErrors.Add(ChainValidationResult.Untrusted);
                streamWebSocket.Control.IgnorableServerCertificateErrors.Add(ChainValidationResult.InvalidName);

                // Add event handler to listen to the ServerCustomValidationRequested event. This enables performing
                // custom validation of the server certificate. The event handler must implement the desired
                // custom certificate validation logic.
                streamWebSocket.ServerCustomValidationRequested += OnServerCustomValidationRequested;

                // Certificate validation is meaningful only for secure connections.
                if (server.Scheme != "wss")
                {
                    AppendOutputLine("Note: Certificate validation is performed only for the wss: scheme.");
                }
            }

            AppendOutputLine($"Connecting to {server}...");
            try
            {
                await streamWebSocket.ConnectAsync(server);
            }
            catch (Exception ex) // For debugging
            {
                streamWebSocket.Dispose();
                streamWebSocket = null;

                AppendOutputLine(MainPage.BuildWebSocketError(ex));
                AppendOutputLine(ex.Message);
                return;
            }
            rootPage.NotifyUser("Connected", NotifyType.StatusMessage);

            // Start a task to continuously read for incoming data
            Task receiving = ReceiveDataAsync(streamWebSocket);

            // Start a task to continuously write outgoing data
            Task sending = SendDataAsync(streamWebSocket);
        }