예제 #1
0
    private void ProcessClientRequests(SystemChannel system)
    {
        PendingMapType pendingMap = (system.CurrentPhase != RequestPhase.STARTUP) ? system.Phases.Running : system.Phases.StartUp;

        foreach (KeyValuePair <uint, ClientRequestType> pair in this.m_state.m_contextIdToRequestMap)
        {
            ClientRequestType type2 = pair.Value;
            if ((!type2.IsSubsribeRequest && (type2.System != null)) && ((type2.System.SystemId == system.SystemId) && (system.PendingResponseTimeout != 0)))
            {
                TimeSpan span = (TimeSpan)(DateTime.Now - type2.SendTime);
                if (span.TotalSeconds >= system.PendingResponseTimeout)
                {
                    this.ScheduleResubscribeWithNewRoute(system);
                    return;
                }
            }
        }
        if (pendingMap.PendingSend.Count > 0)
        {
            ClientRequestType request = pendingMap.PendingSend.Dequeue();
            this.SendToUtil(system, system.Route, request, pendingMap);
        }
        else if ((system.CurrentPhase == RequestPhase.STARTUP) && this.m_state.m_runningPhaseEnabled)
        {
            system.CurrentPhase = RequestPhase.RUNNING;
        }
    }
예제 #2
0
 private void ProcessResponse(PegasusPacket packet, ClientRequestType clientRequest)
 {
     if (packet.Type != 0xfe)
     {
         this.m_state.m_pendingDelivery.Enqueue(packet);
     }
 }
예제 #3
0
    private void NotifyResponseReceivedImpl(PegasusPacket packet)
    {
        uint context = (uint)packet.Context;
        ClientRequestType request = this.GetClientRequest(context, "received_response", true);

        if (request == null)
        {
            if ((packet.Context == 0) || (this.GetDroppedRequest(context, "received_response", true) == null))
            {
                this.m_state.m_pendingDelivery.Enqueue(packet);
            }
        }
        else
        {
            switch (packet.Type)
            {
            case 0x13b:
                this.ProcessSubscribeResponse(packet, request);
                break;

            case 0x148:
                this.ProcessClientRequestResponse(packet, request);
                break;

            default:
                this.ProcessResponse(packet, request);
                break;
            }
        }
    }
예제 #4
0
 private void ProcessSubscribeResponse(PegasusPacket packet, ClientRequestType request)
 {
     if (packet.Body is SubscribeResponse)
     {
         SystemChannel     system   = request.System;
         int               systemId = system.SystemId;
         SubscribeResponse body     = (SubscribeResponse)packet.Body;
         if (body.Result == SubscribeResponse.ResponseResult.FAILED_UNAVAILABLE)
         {
             this.ScheduleResubscribeWithNewRoute(system);
         }
         else
         {
             system.SubscriptionStatus.CurrentState   = SubscriptionStatusType.State.SUBSCRIBED;
             system.SubscriptionStatus.SubscribedTime = DateTime.Now;
             system.Route                   = body.Route;
             system.CurrentPhase            = RequestPhase.STARTUP;
             system.SubscribeAttempt        = 0;
             system.KeepAliveSecs           = body.KeepAliveSecs;
             system.MaxResubscribeAttempts  = body.MaxResubscribeAttempts;
             system.PendingResponseTimeout  = body.PendingResponseTimeout;
             system.PendingSubscribeTimeout = body.PendingSubscribeTimeout;
             this.m_state.m_pendingDelivery.Enqueue(packet);
             system.m_subscribePacketsReceived++;
         }
     }
 }
예제 #5
0
    private void MoveRequestsFromPendingResponseToSend(SystemChannel system, RequestPhase phase, PendingMapType pendingMap)
    {
        List <uint> list  = new List <uint>();
        List <uint> list2 = new List <uint>();

        foreach (KeyValuePair <uint, ClientRequestType> pair in this.m_state.m_contextIdToRequestMap)
        {
            uint key = pair.Key;
            ClientRequestType type = pair.Value;
            if ((type.System.SystemId == system.SystemId) && (phase == type.Phase))
            {
                if (type.ShouldRetryOnError)
                {
                    list.Add(key);
                }
                else
                {
                    list2.Add(key);
                }
            }
        }
        foreach (uint num2 in list)
        {
            string            reason = (phase != RequestPhase.STARTUP) ? "moving_to_pending_running_phase" : "moving_to_pending_startup_phase";
            ClientRequestType item   = this.GetClientRequest(num2, reason, true);
            pendingMap.PendingSend.Enqueue(item);
            this.m_state.m_contextIdToDroppedPacketMap.Add(num2, item);
        }
        foreach (uint num3 in list2)
        {
            ClientRequestType type3 = this.GetClientRequest(num3, "moving_to_dropped", true);
            this.m_state.m_contextIdToDroppedPacketMap.Add(num3, type3);
        }
    }
예제 #6
0
    private void SendSubscriptionRequest(SystemChannel system)
    {
        int systemId = system.SystemId;

        if (system.Route == 0)
        {
            this.MoveRequestsFromPendingResponseToSend(system, RequestPhase.STARTUP, system.Phases.StartUp);
            this.MoveRequestsFromPendingResponseToSend(system, RequestPhase.RUNNING, system.Phases.Running);
        }
        ClientRequestType request = new ClientRequestType {
            Type              = 0x13a,
            SubID             = 0,
            Body              = ProtobufUtil.ToByteArray(this.m_subscribePacket),
            RequestId         = this.GetNextRequestId(),
            IsSubsribeRequest = true
        };

        system.SubscriptionStatus.CurrentState = SubscriptionStatusType.State.PENDING_RESPONSE;
        system.SubscriptionStatus.LastSend     = DateTime.Now;
        PendingMapType pendingMap = (system.CurrentPhase != RequestPhase.STARTUP) ? system.Phases.Running : system.Phases.StartUp;

        system.SubscriptionStatus.ContexId = this.SendToUtil(system, system.Route, request, pendingMap);
        system.SubscribeAttempt++;
        this.m_state.m_subscribePacketsSent++;
    }
예제 #7
0
        public bool SendRequest(out NSError error, ClientRequestType type, string appId)
        {
            bool result = false;

            switch (type)
            {
            case ClientRequestType.GreetMe:
                result = SendGreetMeRequest(out error, appId);
                break;

            case ClientRequestType.BringServiceAppToFront:
                result = BringServiceAppToFront(out error, appId);
                break;

            case ClientRequestType.SendFiles:
                result = SendFilesRequest(out error, appId);
                break;

            case ClientRequestType.GetDateAndTime:
                result = SendGetDateAndTimeRequest(out error, appId);
                break;

            default:
                error = null;
                break;
            }

            return(result);
        }
예제 #8
0
    private ClientRequestType GetDroppedRequest(uint contextId, string reason, bool removeIfFound = true)
    {
        ClientRequestType type = null;

        if (this.m_state.m_contextIdToDroppedPacketMap.TryGetValue(contextId, out type) && removeIfFound)
        {
            this.m_state.m_contextIdToDroppedPacketMap.Remove(contextId);
        }
        return(type);
    }
예제 #9
0
 private void ProcessClientRequestResponse(PegasusPacket packet, ClientRequestType clientRequest)
 {
     if (packet.Body is ClientRequestResponse)
     {
         ClientRequestResponse body = (ClientRequestResponse)packet.Body;
         if (body.ResponseFlags == ClientRequestResponse.ClientRequestResponseFlags.CRRF_SERVICE_UNAVAILABLE)
         {
             this.ProcessServiceUnavailable(body, clientRequest);
         }
     }
 }
예제 #10
0
    private uint SendToUtil(SystemChannel system, ulong route, ClientRequestType request, PendingMapType pendingMap)
    {
        uint key = this.GenerateContextId();

        BattleNet.SendUtilPacket(request.Type, system.SystemId, request.Body, request.Body.Length, request.SubID, (int)key, route);
        request.Context  = key;
        request.System   = system;
        request.SendTime = DateTime.Now;
        this.m_state.m_contextIdToRequestMap.Add(key, request);
        string str = !request.IsSubsribeRequest ? request.Phase.ToString() : "SUBSCRIBE";

        return(key);
    }
예제 #11
0
    private ClientRequestType GetPendingSendRequest(uint contextId, string reason, bool removeIfFound = true)
    {
        ClientRequestType type = null;

        foreach (KeyValuePair <int, SystemChannel> pair in this.m_state.m_systems.Systems)
        {
            SystemChannel channel = pair.Value;
            type = this.GetPendingSendRequestForPhase(contextId, removeIfFound, channel.Phases.Running);
            if (type != null)
            {
                return(type);
            }
            type = this.GetPendingSendRequestForPhase(contextId, removeIfFound, channel.Phases.StartUp);
        }
        return(type);
    }
예제 #12
0
    private bool SendClientRequestImpl(int type, IProtoBuf body, ClientRequestConfig clientRequestConfig, RequestPhase requestPhase, int subID)
    {
        if (type == 0)
        {
            return(false);
        }
        if ((requestPhase < RequestPhase.STARTUP) || (requestPhase > RequestPhase.RUNNING))
        {
            return(false);
        }
        ClientRequestConfig config    = (clientRequestConfig != null) ? clientRequestConfig : this.m_defaultConfig;
        int           requestedSystem = config.RequestedSystem;
        SystemChannel orCreateSystem  = this.GetOrCreateSystem(requestedSystem);

        if (requestPhase < orCreateSystem.CurrentPhase)
        {
            return(false);
        }
        if (orCreateSystem.WasEverInRunningPhase && (requestPhase < RequestPhase.RUNNING))
        {
            return(false);
        }
        if (body == null)
        {
            return(false);
        }
        ClientRequestType item = new ClientRequestType {
            Type = type,
            ShouldRetryOnError = config.ShouldRetryOnError,
            SubID      = subID,
            Body       = ProtobufUtil.ToByteArray(body),
            Phase      = requestPhase,
            RetryCount = 0,
            RequestId  = this.GetNextRequestId()
        };

        if (item.Phase == RequestPhase.STARTUP)
        {
            orCreateSystem.Phases.StartUp.PendingSend.Enqueue(item);
        }
        else
        {
            orCreateSystem.Phases.Running.PendingSend.Enqueue(item);
        }
        return(true);
    }
예제 #13
0
    private bool ShouldIgnoreErrorImpl(BnetErrorInfo errorInfo)
    {
        uint context = (uint)errorInfo.GetContext();

        if (context == 0)
        {
            return(false);
        }
        ClientRequestType clientRequest = this.GetClientRequest(context, "should_ignore_error", true);

        if (clientRequest == null)
        {
            return((this.GetDroppedRequest(context, "should_ignore", true) != null) || (this.GetPendingSendRequest(context, "should_ignore", true) != null));
        }
        BattleNetErrors error = errorInfo.GetError();

        if (clientRequest.IsSubsribeRequest)
        {
            if (clientRequest.System.SubscribeAttempt >= clientRequest.System.MaxResubscribeAttempts)
            {
                return(!clientRequest.ShouldRetryOnError);
            }
            return(true);
        }
        if (!clientRequest.ShouldRetryOnError)
        {
            return(true);
        }
        if (clientRequest.System.PendingResponseTimeout == 0)
        {
            return(false);
        }
        switch (error)
        {
        case (((BattleNetErrors)(BattleNetErrors.ERROR_INTERNAL && BattleNetErrors.ERROR_RPC_REQUEST_TIMED_OUT)) && BattleNetErrors.ERROR_GAME_UTILITY_SERVER_NO_SERVER):
            return(false);
        }
        return(this.ShouldIgnore_ERROR_GAME_UTILITY_SERVER_NO_SERVER(errorInfo, clientRequest));
    }
예제 #14
0
    private ClientRequestType GetPendingSendRequestForPhase(uint contextId, bool removeIfFound, PendingMapType pendingMap)
    {
        ClientRequestType         type  = null;
        Queue <ClientRequestType> queue = new Queue <ClientRequestType>();

        foreach (ClientRequestType type2 in pendingMap.PendingSend)
        {
            if ((type == null) && (type2.Context == contextId))
            {
                type = type2;
                if (!removeIfFound)
                {
                    queue.Enqueue(type2);
                }
            }
            else
            {
                queue.Enqueue(type2);
            }
        }
        pendingMap.PendingSend = queue;
        return(type);
    }
예제 #15
0
        public TimeSpan GetNearTimeInterval(TimeSpan startTime, Schedule schedule,
            ClientRequestType clientRequestType, int subjects = 1)
        {
            // Недоступные интервалы
            var reservedIntervals = new List<TimeInterval>();

            // Перерывы оператора
            reservedIntervals.AddRange(GetIgnoredIntervals(clientRequestType));
            // Запланированные запросы клиентов
            reservedIntervals.AddRange(clientRequestIntervals);

            var clientInterval = TimeSpan.FromTicks(schedule.LiveClientInterval.Ticks * subjects);

            var renderStartTime = startTime;

            foreach (var exception in reservedIntervals
                .Where(i => i.FinishTime >= startTime)
                .OrderBy(i => i.FinishTime))
            {
                var renderFinishTime = exception.StartTime;

                var interval = renderFinishTime - renderStartTime;
                // Найденный интервал обслуживания клиента больше или равен плановому?
                if (interval < clientInterval - schedule.Intersection)
                {
                    renderStartTime = exception.FinishTime;
                }
                else
                {
                    break;
                }
            }

            return renderStartTime;
        }
예제 #16
0
 private bool ShouldIgnore_ERROR_GAME_UTILITY_SERVER_NO_SERVER(BnetErrorInfo errorInfo, ClientRequestType clientRequest)
 {
     this.ScheduleResubscribeWithNewRoute(clientRequest.System);
     return(true);
 }
예제 #17
0
        public async Task<DTO.ServiceFreeTime> GetServiceFreeTime(Guid serviceId, DateTime planDate, ClientRequestType requestType)
        {
            return await Task.Run(() =>
            {
                using (var session = SessionProvider.OpenSession())
                using (var transaction = session.BeginTransaction())
                {
                    var service = session.Get<Service>(serviceId);
                    if (service == null)
                    {
                        throw new FaultException<ObjectNotFoundFault>(new ObjectNotFoundFault(serviceId), string.Format("Услуга [{0}] не найдена", serviceId));
                    }

                    planDate = planDate.Date;

                    QueuePlan queuePlan;

                    if (planDate == DateTime.Today)
                    {
                        queuePlan = QueueInstance.TodayQueuePlan;
                    }
                    else
                    {
                        queuePlan = new QueuePlan();
                        queuePlan.Load(planDate);
                        queuePlan.Build();
                    }

                    try
                    {
                        using (var locker = queuePlan.ReadLock())
                        {
                            var serviceFreeTime = queuePlan.GetServiceFreeTime(service, service.GetFirstStep(session), requestType);
                            return Mapper.Map<ServiceFreeTime, DTO.ServiceFreeTime>(serviceFreeTime);
                        }
                    }
                    catch (Exception exception)
                    {
                        throw new FaultException(exception.Message);
                    }
                }
            });
        }
예제 #18
0
 private void ProcessServiceUnavailable(ClientRequestResponse response, ClientRequestType clientRequest)
 {
     this.ScheduleResubscribeWithNewRoute(clientRequest.System);
 }
예제 #19
0
        private TimeInterval[] GetIgnoredIntervals(ClientRequestType clientRequestType)
        {
            var serviceRenderingMode = clientRequestType == ClientRequestType.Early
                ? ServiceRenderingMode.EarlyRequests
                : ServiceRenderingMode.LiveRequests;

            var formatInfo = DateTimeFormatInfo.CurrentInfo;
            var calendar = formatInfo.Calendar;
            int week = calendar.GetWeekOfYear(PlanDate, CalendarWeekRule.FirstFourDayWeek, formatInfo.FirstDayOfWeek);

            return Interruptions.Where(i => i.ServiceRenderingMode == ServiceRenderingMode.AllRequests
                        || i.ServiceRenderingMode == serviceRenderingMode)
                .Select(i => new TimeInterval(i.StartTime, i.FinishTime))
                .ToArray();
        }
예제 #20
0
        /// <summary>
        /// Получить доступные временные интервалы
        /// </summary>
        public ServiceFreeTime GetServiceFreeTime(Service service, ServiceStep serviceStep, ClientRequestType requestType, int subjects = 1)
        {
            var schedule = GetServiceSchedule(service);
            if (schedule == null)
            {
                throw new Exception("Не удалось определить расписание для услуги");
            }

            if (!schedule.IsWorked)
            {
                throw new Exception("На указанную дату услуга не оказывается");
            }

            switch (requestType)
            {
                case ClientRequestType.Live:
                    if (!schedule.RenderingMode.HasFlag(ServiceRenderingMode.LiveRequests))
                    {
                        throw new Exception("Живая очередь для данной услуги на указанный день отключена");
                    }
                    break;

                case ClientRequestType.Early:
                    if (!schedule.RenderingMode.HasFlag(ServiceRenderingMode.EarlyRequests))
                    {
                        throw new Exception("Предварительная запись для данной услуги на указанный день отключена");
                    }

                    break;
            }

            var report = new List<string>()
            {
                string.Format("Поиск свободного времени на дату {0:dd.MM.yyyy} и время {1:hh\\:mm\\:ss}", PlanDate, PlanTime)
            };

            // Только подходящие параметры обслуживания
            var serviceRenderingMode = requestType == ClientRequestType.Early
                ? ServiceRenderingMode.EarlyRequests
                : ServiceRenderingMode.LiveRequests;

            report.Add(string.Format("Выбран режим обслуживания [{0}]", serviceRenderingMode));

            var renderings = GetServiceRenderings(schedule, serviceStep, serviceRenderingMode);

            var potentialOperatorsPlans = OperatorsPlans
                .Where(p => renderings.Any(r => r.Operator.IsActive && r.Operator.Equals(p.Operator)))
                .ToList();

            if (potentialOperatorsPlans.Count == 0)
            {
                throw new Exception("В системе нет активных операторов способных оказать услугу");
            }

            report.Add("Найдены следующие потенциальные планы операторов");
            foreach (var o in potentialOperatorsPlans)
            {
                report.Add(o.ToString());
            }

            if (PlanDate == DateTime.Today && schedule.OnlineOperatorsOnly)
            {
                potentialOperatorsPlans.RemoveAll(o => !o.Operator.Online);
                report.Add("Оставлены только операторы онлайн");
                foreach (var o in potentialOperatorsPlans)
                {
                    report.Add(o.ToString());
                }
            }

            var timeIntervals = new List<TimeSpan>();

            var startTime = schedule.StartTime;
            if (PlanTime > startTime)
            {
                startTime = PlanTime;
            }

            report.Add(string.Format("Поиск интервалов времени с {0:hh\\:mm\\:ss}", startTime));

            var clientInterval = requestType == ClientRequestType.Live
                ? schedule.LiveClientInterval : schedule.EarlyClientInterval;

            int openedRequests = 0;

            foreach (var potentialOperatorPlan in potentialOperatorsPlans)
            {
                openedRequests += potentialOperatorPlan.ClientRequestPlans
                    .Select(p => p.ClientRequest)
                    .Count(r => r.Type == requestType);

                report.Add(string.Format("В плане оператора [{0}] {1} открытых запросов", potentialOperatorPlan, openedRequests));

                var intervalTime = startTime;

                while (intervalTime < schedule.FinishTime)
                {
                    intervalTime = potentialOperatorPlan.GetNearTimeInterval(intervalTime, schedule, requestType, subjects);

                    report.Add(string.Format("Найден ближайший интвервал времени {0:hh\\:mm\\:ss}", intervalTime));

                    var timeIntervalRounding = service.TimeIntervalRounding;
                    if (timeIntervalRounding != TimeSpan.Zero)
                    {
                        var rounding = new TimeSpan(intervalTime.Ticks % timeIntervalRounding.Ticks);
                        if (rounding != TimeSpan.Zero)
                        {
                            report.Add(string.Format("Округление интервала {0:hh\\:mm\\:ss}", rounding));

                            intervalTime = intervalTime.Add(rounding <= schedule.Intersection ? -rounding : timeIntervalRounding.Subtract(rounding));
                        }
                    }

                    report.Add(string.Format("Найден интвервал времени {0:hh\\:mm\\:ss}", intervalTime));

                    timeIntervals.Add(intervalTime);
                    intervalTime = intervalTime.Add(clientInterval);

                    if (timeIntervals.Count() > 1000)
                    {
                        throw new OverflowException("Возможно переполнение памяти. Обратитесь к администратору.");
                    }
                }
            }

            int freeTimeIntervals;

            if (PlanDate != DateTime.Today)
            {
                int maxOnlineOperators = schedule.MaxOnlineOperators > 0 ? schedule.MaxOnlineOperators : potentialOperatorsPlans.Count;

                int maxRequests = (int)((schedule.EarlyFinishTime - schedule.EarlyStartTime).Ticks / clientInterval.Ticks) * maxOnlineOperators;
                report.Add(string.Format("Максимальное кол-во запросов {0}", maxRequests));

                int maxEarlyClientRequests = maxRequests * schedule.EarlyReservation / 100;
                report.Add(string.Format("Максимальное кол-во запросов с учетом резервирования {0}", maxEarlyClientRequests));

                freeTimeIntervals = maxEarlyClientRequests - openedRequests;
                if (freeTimeIntervals <= 0)
                {
                    throw new Exception("Возможности резервирования для данной услуги на указанный день исчерпаны");
                }

                timeIntervals.RemoveAll(i => i < schedule.EarlyStartTime);
                timeIntervals.RemoveAll(i => i.Add(clientInterval - schedule.Intersection) > schedule.EarlyFinishTime);

                if (freeTimeIntervals > timeIntervals.Count)
                {
                    freeTimeIntervals = timeIntervals.Count;
                }
            }
            else
            {
                timeIntervals.RemoveAll(i => i.Add(clientInterval - schedule.Intersection) > schedule.FinishTime);

                freeTimeIntervals = timeIntervals.Count;
            }

            return new ServiceFreeTime()
            {
                Service = service,
                Schedule = schedule,
                TimeIntervals = timeIntervals.ToArray(),
                FreeTimeIntervals = freeTimeIntervals,
                Report = report
            };
        }
예제 #21
0
 public ClientRequestCreatedEvent(Client client, string clientId, string requestId, ClientRequestType requestType) : base(client)
 {
     ClientId    = clientId;
     RequestId   = requestId;
     RequestType = requestType;
 }
        private async void SelectType(ClientRequestType type)
        {
            Model.RequestType = type;

            await Model.AdjustMaxSubjects();
            Navigator.NextPage();
        }