private async Task ConnectAsync(CancellationToken cancellationToken) { while (!cancellationToken.IsCancellationRequested) { CloudServiceOptions options = null; try { _isConnected = false; if (!_storageService.TryReadOrCreate(out options, CloudServiceOptions.Filename) || options == null) { continue; } if (!options.IsEnabled) { continue; } if (string.IsNullOrEmpty(options.IdentityUid) || string.IsNullOrEmpty(options.Password)) { continue; } using (var webSocketClient = new ClientWebSocket()) { using (var timeout = new CancellationTokenSource(options.ReconnectDelay)) { var url = $"wss://{options.Host}/Connector"; webSocketClient.Options.SetRequestHeader(CustomCloudHeaderNames.IdentityUid, options.IdentityUid); webSocketClient.Options.SetRequestHeader(CustomCloudHeaderNames.ChannelUid, options.ChannelUid); webSocketClient.Options.SetRequestHeader(CustomCloudHeaderNames.Password, options.Password); webSocketClient.Options.SetRequestHeader(CustomCloudHeaderNames.Version, WirehomeCoreVersion.Version); await webSocketClient.ConnectAsync(new Uri(url, UriKind.Absolute), timeout.Token).ConfigureAwait(false); } _channel = new ConnectorChannel(webSocketClient, _cloudMessageSerializer, _logger); _logger.LogInformation($"Connected with Wirehome.Cloud at host '{options.Host}'."); _isConnected = true; while (_channel.IsConnected && !cancellationToken.IsCancellationRequested) { var receiveResult = await _channel.ReceiveAsync(cancellationToken).ConfigureAwait(false); if (receiveResult.CloseConnection || cancellationToken.IsCancellationRequested) { webSocketClient.Abort(); break; } if (receiveResult.Message == null) { continue; } ParallelTask.Start(() => TryProcessCloudMessageAsync(receiveResult.Message, cancellationToken), cancellationToken, _logger); } } } catch (Exception exception) { _logger.LogError(exception, $"Error while connecting with Wirehome.Cloud service at host '{options?.Host}'."); } finally { _isConnected = false; _channel = null; var delay = TimeSpan.FromSeconds(10); if (options != null && options.ReconnectDelay > TimeSpan.Zero) { delay = options.ReconnectDelay; } await Task.Delay(delay, cancellationToken).ConfigureAwait(false); } } }
async Task ConnectAsync(CancellationToken cancellationToken) { while (!cancellationToken.IsCancellationRequested) { try { _isConnected = false; if (!_storageService.SafeReadSerializedValue(out _options, DefaultDirectoryNames.Configuration, CloudServiceOptions.Filename) || _options == null) { continue; } if (!_options.IsEnabled) { continue; } if (string.IsNullOrEmpty(_options.ChannelAccessToken)) { continue; } using (var webSocketClient = new ClientWebSocket()) { using (var timeout = new CancellationTokenSource(_options.ReconnectDelay)) { var url = $"wss://{_options.Host}/Connector"; webSocketClient.Options.SetRequestHeader(CloudHeaderNames.ChannelAccessToken, _options.ChannelAccessToken); webSocketClient.Options.SetRequestHeader(CloudHeaderNames.Version, WirehomeCoreVersion.Version); await webSocketClient.ConnectAsync(new Uri(url, UriKind.Absolute), timeout.Token) .ConfigureAwait(false); } var channelOptions = new ConnectorChannelOptions { UseCompression = _options.UseCompression }; _channel = new ConnectorChannel(channelOptions, webSocketClient, _cloudMessageSerializer, _logger); _isConnected = true; _connectionError = null; _logger.LogInformation($"Connected with Wirehome.Cloud at host '{_options.Host}'."); while (_channel.IsConnected && !cancellationToken.IsCancellationRequested) { var receiveResult = await _channel.ReceiveAsync(cancellationToken).ConfigureAwait(false); if (receiveResult.CloseConnection || cancellationToken.IsCancellationRequested) { webSocketClient.Abort(); break; } if (receiveResult.Message == null) { continue; } ParallelTask.Start( () => TryProcessCloudMessageAsync(receiveResult.Message, cancellationToken), cancellationToken, _logger); } } } catch (OperationCanceledException) { } catch (Exception exception) { _connectionError = exception; _logger.LogError(exception, $"Error while connecting with Wirehome.Cloud service at host '{_options?.Host}'."); } finally { _isConnected = false; _channel = null; var delay = TimeSpan.FromSeconds(10); if (_options != null && _options.ReconnectDelay > TimeSpan.Zero) { delay = _options.ReconnectDelay; } await Task.Delay(delay, cancellationToken).ConfigureAwait(false); } } }