private void WaitForPingResponse(object identifier)
        {
            var identifierMtbl = (HubClientIdentifierMtbl)identifier;
            var task           = WaitForPingResponseAsync(identifierMtbl);

            task.Wait();
            bool singleInstanceAlreadyRegistered = task.Result;

            Task <Tuple <bool, HubClientIdentifierMtbl> > pingTask;
            var registeredIdentifier = RegisteredIdentifier;

            if (!singleInstanceAlreadyRegistered)
            {
                lock (syncRoot)
                {
                    RegisteredIdentifier = candidateIdentifier;
                    registeredIdentifier = candidateIdentifier;
                }
            }

            registeredInstanceResponded = true;
            pingRequestSent             = false;
            candidateIdentifier         = null;

            pingTask = mainHubContext.Clients.All.TrySendClientPingResponseAsync(
                singleInstanceAlreadyRegistered, registeredIdentifier);

            pingTask.Wait();
        }
        private async Task <bool> WaitForPingResponseAsync(HubClientIdentifierMtbl identifier)
        {
            bool singleInstanceAlreadyRegistered = this.isRegistered;
            bool waitForResponse = !this.registeredInstanceResponded;

            int waitMillis      = HubsH.PING_RESPONSE_WAIT_MILLIS;
            int totalWaitMillis = 0;

            int totalWaitMillisAggMax = HubsH.PING_RESPONSE_WAIT_MILLIS_AGG_MAX;

            while (waitForResponse && (
                       totalWaitMillis < totalWaitMillisAggMax))
            {
                lock (syncRoot)
                {
                    waitForResponse = !this.registeredInstanceResponded;
                    singleInstanceAlreadyRegistered = this.isRegistered;

                    isRegistered = true;
                }

                if (waitForResponse)
                {
                    await Task.Delay(waitMillis);

                    totalWaitMillis += waitMillis;
                }
            }

            return(singleInstanceAlreadyRegistered);
        }
示例#3
0
文件: App.cs 项目: dantincu/turmerik
        private async Task RunAsSingleInstanceCoreAsync(IProgramArgs args)
        {
            var tuple = await hubConnection.InvokeAsync <Tuple <bool, HubClientIdentifierMtbl> >(
                tryRegisterSingleInstanceMethodName);

            hubClientIdentifier = tuple.Item2;

            if (tuple.Item1)
            {
                RunCore(args);
            }
            else
            {
                bool singleInstanceAlreadyRegistered = await WaitForClientPingResponse();

                if (!singleInstanceAlreadyRegistered)
                {
                    RunCore(args);
                }
                else
                {
                    await UnregisterSingleInstanceAsync();
                }
            }
        }
        public virtual bool IdentifierIsNullOrEmpty(HubClientIdentifierMtbl identifier)
        {
            bool retVal = identifier == null || identifier.Uuid == Guid.Empty;

            retVal = retVal || string.IsNullOrWhiteSpace(identifier?.ConnectionId);

            return(retVal);
        }
示例#5
0
        public async Task <Tuple <bool, HubClientIdentifierMtbl> > TryUnregisterSingleInstanceAsync(
            HubClientIdentifierMtbl hubClientIdentifier)
        {
            bool retVal = await singleHubClientInstance.TryUnregisterSingleInstanceAsync(
                hubClientIdentifier);

            var retTuple = new Tuple <bool, HubClientIdentifierMtbl>(
                retVal, hubClientIdentifier);

            return(retTuple);
        }
示例#6
0
        public async Task <Tuple <bool, HubClientIdentifierMtbl> > TryReceiveClientPingResponseAsync(
            HubClientIdentifierMtbl hubClientIdentifier)
        {
            bool retVal = await singleHubClientInstance.PingClientRespondedAsync(hubClientIdentifier);

            await Clients.All.TrySendClientPingResponseAsync(retVal, hubClientIdentifier);

            var retTuple = new Tuple <bool, HubClientIdentifierMtbl>(
                retVal, hubClientIdentifier);

            return(retTuple);
        }
        public async Task <bool> ClientIsRegisteredAsync(HubClientIdentifierMtbl identifier)
        {
            bool retVal;

            lock (syncRoot)
            {
                retVal = isRegistered && this.IdentifiersAreEqual(
                    identifier,
                    this.RegisteredIdentifier);
            }

            return(retVal);
        }
        public virtual bool IdentifiersAreEqual(HubClientIdentifierMtbl trgIdnf, HubClientIdentifierMtbl refIdnf)
        {
            bool bothAreNull = trgIdnf == null && refIdnf == null;
            bool noneAreNull = trgIdnf != null && refIdnf != null;

            bool retVal = bothAreNull || noneAreNull;

            if (retVal && noneAreNull)
            {
                retVal = trgIdnf.Uuid == refIdnf.Uuid;
            }

            return(retVal);
        }
示例#9
0
        public async Task <Tuple <bool, HubClientIdentifierMtbl> > TryRegisterSingleInstanceAsync()
        {
            var hubClientIdentifier = new HubClientIdentifierMtbl
            {
                Uuid         = Guid.NewGuid(),
                ConnectionId = Context.ConnectionId
            };

            bool retVal = await singleHubClientInstance.TryRegisterSingleInstanceAsync(hubClientIdentifier);

            var retTuple = new Tuple <bool, HubClientIdentifierMtbl>(
                retVal, hubClientIdentifier);

            return(retTuple);
        }
        public async Task <bool> TryRegisterSingleInstanceAsync(HubClientIdentifierMtbl identifier)
        {
            bool retVal;

            if (IdentifierIsNullOrEmpty(identifier))
            {
                throw new ArgumentNullException(nameof(identifier));
            }

            bool sendPingRequest;

            lock (syncRoot)
            {
                retVal          = !isRegistered;
                sendPingRequest = !retVal;

                if (retVal)
                {
                    isRegistered         = true;
                    RegisteredIdentifier = identifier;
                }
                else if (!pingRequestSent)
                {
                    candidateIdentifier = identifier;

                    registeredInstanceResponded = false;
                    pingRequestSent             = true;
                }
                else
                {
                    sendPingRequest = false;
                }
            }

            if (sendPingRequest)
            {
                pingWaitThread = new Thread(WaitForPingResponse);
                pingWaitThread.Start(identifier);

                await mainHubContext.Clients.All.TryPingClientAsync(identifier);
            }

            return(retVal);
        }
        public async Task <bool> TryUnregisterSingleInstanceAsync(HubClientIdentifierMtbl identifier)
        {
            bool retVal;

            lock (syncRoot)
            {
                retVal = isRegistered && this.IdentifiersAreEqual(
                    identifier,
                    this.RegisteredIdentifier);

                if (retVal)
                {
                    isRegistered = false;
                    this.RegisteredIdentifier = default;
                }
            }

            return(retVal);
        }
        public async Task <bool> PingClientRespondedAsync(HubClientIdentifierMtbl identifier)
        {
            bool retVal;

            if (IdentifierIsNullOrEmpty(identifier))
            {
                throw new ArgumentException(nameof(identifier));
            }

            lock (syncRoot)
            {
                retVal = isRegistered && this.IdentifiersAreEqual(
                    identifier,
                    this.RegisteredIdentifier);

                if (retVal)
                {
                    registeredInstanceResponded = true;
                }
            }

            return(retVal);
        }