示例#1
0
        protected void OnReceiveMessage(ReceiveMessage message)
        {
            ATL.WriteLine($"Subscriber received: {message}");

            switch (message.Type)
            {
            case ReceiveMessage.SubscribeType:
            {
                if (message.Data is SubscriptionMessageData _data && _data.StatusCode == ReceiveMessageStatusCode.Success)
                {
                    ConfirmSubscribed(_data.Path);
                }
                break;
            }

            case ReceiveMessage.UnsubscribeType:
            {
                if (message.Data is SubscriptionMessageData _data && _data.StatusCode == ReceiveMessageStatusCode.Success)
                {
                    RemoveSubscribed(_data.Path);
                }
                break;
            }

            case ReceiveMessage.ChangedType:
            {
                if (message.Data is IEnumerable <ConfigKey> _configKeys)
                {
                    // Raises receive callback.
                    m_ReceiveCallback(_configKeys);
                }
                break;
            }

            case ReceiveMessage.DeletedType:
            {
                if (message.Data is string _path)
                {
                    RemoveSubscribed(_path);

                    // Raises deleted callback.
                    m_DeletedCallback(_path);
                }
                break;
            }
            }
        }
示例#2
0
        protected async Task ConnectAsync(CancellationToken cancellationToken)
        {
            // Creates socket client.
            var _client = new TSocketClient();

            _client.SetRequestHeader(AppIdName, Settings.ApplicationId);

            // Connects the web socket.
            await _client.ConnectAsync(GetSubscribeUrl(Settings.ApiUrl), cancellationToken).ConfigureAwait(true);

            // Try to dispose previous websocket.
            if (m_Client != null)
            {
                m_Client.Dispose();
            }
            m_Client = _client;

            ATL.WriteLine("Subscriber connected");
        }
示例#3
0
        private async Task Reconnect(CancellationToken cancellationToken)
        {
            ATL.WriteLine("Subscriber reconnecting");

            await m_SyncRoot.WaitAsync(m_CancellationTokenSource.Token);

            var _subscribed  = m_Subscribed;
            var _initialized = m_Initialized;

            try
            {
                // Reset internals before reconnect.
                m_Initialized = false;
                m_Subscribed  = null;

                foreach (var _item in _subscribed)
                {
                    if (_item.Confirmed)
                    {
                        await SubscribeAsyncInternal(_item.Path, _item.Properties, cancellationToken);
                    }
                }

                ATL.WriteLine("Subscriber reconnected");
            }
            catch (Exception _ex)
            {
                ATL.WriteLine("Subscriber reconnect failed");

                // Restore internals.
                m_Initialized = _initialized;
                m_Subscribed  = _subscribed;

                // Throw connection closed exception to attemp reconnect again.
                throw new ConnectionClosedException(true, (_ex as WebSocketException)?.ErrorCode ?? 0, _ex);
            }
            finally
            {
                m_SyncRoot.Release();
            }
        }
示例#4
0
        private void ReceiveImpl(Task _)
        {
            if (Interlocked.CompareExchange(ref m_ReceiveState, m_RECEIVE_STATE_ACTIVE, m_RECEIVE_STATE_NONE) != m_RECEIVE_STATE_NONE)
            {
                return;
            }

            var _cancellationToken = m_CancellationTokenSource.Token;

            Task.Run(async() =>
            {
                var _reconnectCounter = 0;
                var _reconnect        = false;
                do
                {
                    try
                    {
                        // Try reconnect if requires.
                        if (_reconnect)
                        {
                            // Delay before reconnect.
                            // Delay time will increase till 5 minutes of end.
                            // Used fot this following formula: initial * (log(counter, increase_factor) + 1) => maximum is 5 minutes, initial is 30 seconds.
                            // To skip increasing delay have to set 0 for ReconnectInitDelay.
                            var _delay = (int)(ReconnectInitDelay * (Math.Log(++_reconnectCounter, 10.88632d) + 1));
                            if (_delay < 1)
                            {
                                _delay = 1;
                            }
                            Debug.WriteLine($"Reconnects after {_delay / 1000} seconds");
                            await Task.Delay(_delay, _cancellationToken);

                            // Reconnect the all subscriptions.
                            Debug.WriteLine("Reconnecting");
                            await Reconnect(_cancellationToken);
                        }

                        while (!_cancellationToken.IsCancellationRequested)
                        {
                            var _memory = new MemoryStream();
                            try
                            {
                                // Received respose from source.
                                if (await ReceiveAsync(_memory, _cancellationToken))
                                {
                                    // Gets received message.
                                    _memory.Seek(0, SeekOrigin.Begin);
                                    var _message = JsonSerializer.Deserialize <ReceiveMessage>(_memory);

                                    // Invokes implementation of after receive message.
                                    OnReceiveMessage(_message);
                                }
                            }
                            catch (ConnectionClosedException _ex)
                            {
                                ATL.WriteLine($"Subscriber closed({_ex.ErrorCode})");
                                throw;
                            }
                            catch (OperationCanceledException)
                            {
                                throw;
                            }
                            catch (Exception _ex)
                            {
                                Debug.WriteLine($"Occured error: {_ex.Message}");
                            }
                        }
                    }
                    catch (OperationCanceledException)
                    {
                        Debug.WriteLine("Cancelled");
                        _reconnect = false;
                    }
                    catch (ConnectionClosedException _ex)
                    {
                        Debug.WriteLine($"Disconnected ({_ex.ErrorCode})");
                        _reconnect = _ex.Reconnect && Settings.ReconnectSubscriptions;

                        if (!_reconnect)
                        {
                            throw;
                        }
                    }
                    catch (Exception _ex)
                    {
                        Debug.WriteLine($"Occured error: {_ex.Message}");
                        _reconnect = false;
                    }
                }while (_reconnect && !_cancellationToken.IsCancellationRequested);
            }, _cancellationToken);
        }
示例#5
0
        protected async Task SendCommandAsync(WsCommand command, CancellationToken cancellationToken)
        {
            await m_Client.SendAsync(command.GetBinary(), WebSocketMessageType.Text, true, cancellationToken);

            ATL.WriteLine($"Subscriber send: {command}");
        }