Пример #1
0
        private async void RetryRpc()
        {
            OnRetryStarted.OnNext(this);
            var retryCount = 10;

            Debug.Log($"Retry rpc connection. (count: {retryCount})");
            while (retryCount > 0)
            {
                await Task.Delay(5000);

                _hub = StreamingHubClient.Connect <IActionEvaluationHub, IActionEvaluationHubReceiver>(_channel, this);
                try
                {
                    Debug.Log($"Trying to join hub...");
                    await _hub.JoinAsync();

                    Debug.Log($"Join complete! Registering disconnect event...");
                    RegisterDisconnectEvent(_hub);
                    UpdateSubscribeAddresses();
                    OnRetryEnded.OnNext(this);
                    return;
                }
                catch (RpcException re)
                {
                    Debug.LogWarning($"RpcException occurred. Retrying... {retryCount}\n{re}");
                    retryCount--;
                }
                catch (ObjectDisposedException ode)
                {
                    Debug.LogWarning($"ObjectDisposedException occurred. Retrying... {retryCount}\n{ode}");
                    retryCount--;
                }
                catch (Exception e)
                {
                    Debug.LogWarning($"Unexpected error occurred during rpc connection. {e}");
                    break;
                }
            }

            Connected = false;
            OnDisconnected.OnNext(this);
        }
Пример #2
0
        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            await Task.Delay(1000, stoppingToken);

            _client = StreamingHubClient.Connect <IActionEvaluationHub, IActionEvaluationHubReceiver>(
                new Channel(_host, _port, ChannelCredentials.Insecure),
                null
                );
            await _client.JoinAsync();

            _blockRenderer.EveryBlock().Subscribe(
                async pair =>
                await _client.BroadcastRenderBlockAsync(
                    pair.OldTip.Header.Serialize(),
                    pair.NewTip.Header.Serialize()
                    ),
                stoppingToken
                );

            _blockRenderer.EveryReorg().Subscribe(
                async ev =>
                await _client.ReportReorgAsync(
                    ev.OldTip.Serialize(),
                    ev.NewTip.Serialize(),
                    ev.Branchpoint.Serialize()
                    ),
                stoppingToken
                );

            _blockRenderer.EveryReorgEnd().Subscribe(
                async ev =>
                await _client.ReportReorgEndAsync(
                    ev.OldTip.Serialize(),
                    ev.NewTip.Serialize(),
                    ev.Branchpoint.Serialize()
                    ),
                stoppingToken
                );

            _actionRenderer.EveryRender <ActionBase>()
            .Where(ContainsAddressToBroadcast)
            .Subscribe(
                async ev =>
            {
                var formatter = new BinaryFormatter();
                using var c   = new MemoryStream();
                using var df  = new DeflateStream(c, System.IO.Compression.CompressionLevel.Fastest);

                try
                {
                    formatter.Serialize(df, ev);
                    await _client.BroadcastRenderAsync(c.ToArray());
                }
                catch (SerializationException se)
                {
                    // FIXME add logger as property
                    Log.Error(se, "Skip broadcasting render since the given action isn't serializable.");
                }
                catch (Exception e)
                {
                    // FIXME add logger as property
                    Log.Error(e, "Skip broadcasting render due to the unexpected exception");
                }
            },
                stoppingToken
                );

            _actionRenderer.EveryUnrender <ActionBase>()
            .Where(ContainsAddressToBroadcast)
            .Subscribe(
                async ev =>
            {
                var formatter = new BinaryFormatter();
                using var c   = new MemoryStream();
                using var df  = new DeflateStream(c, System.IO.Compression.CompressionLevel.Fastest);

                try
                {
                    formatter.Serialize(df, ev);
                    await _client.BroadcastUnrenderAsync(c.ToArray());
                }
                catch (SerializationException se)
                {
                    // FIXME add logger as property
                    Log.Error(se, "Skip broadcasting unrender since the given action isn't serializable.");
                }
                catch (Exception e)
                {
                    // FIXME add logger as property
                    Log.Error(e, "Skip broadcasting unrender due to the unexpected exception");
                }
            },
                stoppingToken
                );

            _exceptionRenderer.EveryException().Subscribe(
                async tuple =>
            {
                var(code, message) = tuple;
                await _client.ReportExceptionAsync((int)code, message);
            },
                stoppingToken
                );

            _nodeStatusRenderer.EveryChangedStatus().Subscribe(
                async isPreloadStarted =>
            {
                if (isPreloadStarted)
                {
                    await _client.PreloadStartAsync();
                }
                else
                {
                    await _client.PreloadEndAsync();
                }
            },
                stoppingToken
                );
        }
Пример #3
0
        private IEnumerator CoJoin(Action <bool> callback)
        {
            Task t = Task.Run(async() =>
            {
                await _hub.JoinAsync();
            });

            yield return(new WaitUntil(() => t.IsCompleted));

            if (t.IsFaulted)
            {
                callback?.Invoke(false);
                yield break;
            }

            Connected = true;

            // 에이전트의 상태를 한 번 동기화 한다.
            Currency goldCurrency = new GoldCurrencyState(
                (Dictionary)GetState(GoldCurrencyState.Address)
                ).Currency;

            States.Instance.SetAgentState(
                GetState(Address) is Bencodex.Types.Dictionary agentDict
                    ? new AgentState(agentDict)
                    : new AgentState(Address));
            States.Instance.SetGoldBalanceState(
                new GoldBalanceState(Address, GetBalance(Address, goldCurrency)));

            // 랭킹의 상태를 한 번 동기화 한다.
            for (var i = 0; i < RankingState.RankingMapCapacity; ++i)
            {
                var address  = RankingState.Derive(i);
                var mapState = GetState(address) is Bencodex.Types.Dictionary serialized
                    ? new RankingMapState(serialized)
                    : new RankingMapState(address);
                States.Instance.SetRankingMapStates(mapState);
            }

            // 상점의 상태를 한 번 동기화 한다.
            States.Instance.SetShopState(
                GetState(ShopState.Address) is Bencodex.Types.Dictionary shopDict
                    ? new ShopState(shopDict)
                    : new ShopState());

            if (GetState(GameConfigState.Address) is Dictionary configDict)
            {
                States.Instance.SetGameConfigState(new GameConfigState(configDict));
            }
            else
            {
                throw new FailedToInstantiateStateException <GameConfigState>();
            }

            if (ArenaHelper.TryGetThisWeekState(BlockIndex, out var weeklyArenaState))
            {
                States.Instance.SetWeeklyArenaState(weeklyArenaState);
            }
            else
            {
                throw new FailedToInstantiateStateException <WeeklyArenaState>();
            }

            ActionRenderHandler.Instance.GoldCurrency = goldCurrency;

            // 그리고 모든 액션에 대한 랜더와 언랜더를 핸들링하기 시작한다.
            BlockRenderHandler.Instance.Start(BlockRenderer);
            ActionRenderHandler.Instance.Start(ActionRenderer);
            ActionUnrenderHandler.Instance.Start(ActionRenderer);

            UpdateSubscribeAddresses();
            callback?.Invoke(true);
        }