Exemplo n.º 1
0
        public async Task RunAsync(ChannelIdentifier channelIdentifier, WebSocket webSocket, CancellationToken cancellationToken)
        {
            if (webSocket == null)
            {
                throw new ArgumentNullException(nameof(webSocket));
            }

            var channelOptions = new ConnectorChannelOptions
            {
                UseCompression = true
            };

            var channel = new ConnectorChannel(channelOptions, webSocket, _cloudMessageSerializer, _logger);

            try
            {
                var openChannel = new OpenChannel(channelIdentifier, channel, _logger);
                lock (_openChannels)
                {
                    _openChannels[channelIdentifier] = openChannel;
                }

                await openChannel.RunAsync(cancellationToken).ConfigureAwait(false);
            }
            finally
            {
                lock (_openChannels)
                {
                    _openChannels.Remove(channelIdentifier);
                }
            }
        }
Exemplo n.º 2
0
        async Task ConnectAsync(CancellationToken cancellationToken)
        {
            while (!cancellationToken.IsCancellationRequested)
            {
                try
                {
                    _isConnected = false;

                    if (!_storageService.TryReadOrCreate(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 (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);
                }
            }
        }