예제 #1
0
        private async Task ConnectAsync(CancellationToken cancellationToken)
        {
            while (!cancellationToken.IsCancellationRequested)
            {
                try
                {
                    _isConnected = false;

                    if (string.IsNullOrEmpty(_options.IdentityUid) || string.IsNullOrEmpty(_options.Password))
                    {
                        continue;
                    }

                    using (var webSocketClient = new ClientWebSocket())
                    {
                        using (var timeout = new CancellationTokenSource(_options.ReconnectDelay))
                        {
                            var encodedIdentityUid = HttpUtility.UrlEncode(_options.IdentityUid);
                            var encodedChannelUid  = HttpUtility.UrlEncode(_options.ChannelUid);
                            var encodedPassword    = HttpUtility.UrlEncode(_options.Password);

                            var url = $"wss://{_options.Host}/Connectors/{encodedIdentityUid}/Channels/{encodedChannelUid}?password={encodedPassword}";
                            await webSocketClient.ConnectAsync(new Uri(url, UriKind.Absolute), timeout.Token).ConfigureAwait(false);
                        }

                        _channel = new ConnectorChannel(webSocketClient, _logger);
                        _logger.LogInformation($"Connected with Wirehome.Cloud at host '{_options.Host}'.");
                        _isConnected = true;

                        while (_channel.IsConnected && !cancellationToken.IsCancellationRequested)
                        {
                            var receiveResult = await _channel.ReceiveMessageAsync(cancellationToken).ConfigureAwait(false);

                            if (receiveResult.CloseConnection || cancellationToken.IsCancellationRequested)
                            {
                                break;
                            }

                            if (receiveResult.Message == null)
                            {
                                continue;
                            }

                            ParallelTask.Start(() => TryProcessCloudMessageAsync(receiveResult.Message, cancellationToken), cancellationToken, _logger);
                        }
                    }
                }
                catch (Exception exception)
                {
                    _isConnected = false;
                    _channel     = null;

                    _logger.LogError(exception, $"Error while connecting with Wirehome.Cloud service at host '{_options.Host}'.");
                }
                finally
                {
                    await Task.Delay(TimeSpan.FromSeconds(10), cancellationToken).ConfigureAwait(false);
                }
            }
        }
예제 #2
0
        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);
                }
            }
        }
예제 #3
0
        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);
                }
            }
        }