Exemple #1
0
        public ActorRestApiGW(IActorRef actorCallDistributor)
        {
            IActorRef originalSender;

            logger = Context.GetLogger();

            Receive <CMDListQueues>(msg =>
            {
                originalSender   = Sender;
                RESQueueList rql = actorCallDistributor.Ask <RESQueueList>(msg).Result;
                rql.Nombre       = "Ahi lo mando ";
                RESJson rqljson  = new RESJson()
                {
                    JsonString = JsonConvert.SerializeObject(rql)
                };

                originalSender.Tell(rqljson, Self);

                logger.Info("=> ResJson FROM Nancy: " + rqljson.JsonString);
            });
        }
Exemple #2
0
        /// <summary>
        /// Esta clase va a manejar la relación colas <-> miembros
        /// Mantiene una lista de todos los miembros logeados (y los que no) y el estado de su dispositivo
        /// Interactua con el ActorQueueRouter
        /// </summary>
        public ActorCallDistributor(IActorRef actorDataAccess, IActorRef actorQueueLog)
        {
            callSenders          = new Dictionary <long, IActorRef>();
            this.actorDataAccess = actorDataAccess;
            //solicita todas las colas que estan persistidas (estaticas) tal vez desde el mysql? como hago para manejar la actualización de valores?
            this.actorDataAccess.Tell(new DAGetQueues());

            queueSystem = new QueueSystemManager();

            //Creo las colas que tengo persistidas
            Receive <DAQueues>(daq =>
            {
                if (daq.Queues != null)
                {
                    foreach (DTOQueue dtoq in daq.Queues)
                    {
                        Queue q = new Queue(dtoq.MemberStrategy, dtoq.CallOrderStrategy)
                        {
                            Id = dtoq.Id, Media = dtoq.Media, MediaType = dtoq.MediaType, Weight = dtoq.Weight, WrapupTime = dtoq.WrapupTime
                        };

                        if (dtoq.QueueMembers != null)
                        {
                            //foreach(DTOQueueMember qm in dtoq.QueueMembers)
                            //{
                            //TODO: revisar esto, me parece que esta demás, de la freepbx por ejemplo no puedo obtebner esta info
                            //}
                        }

                        queueSystem.QueueCache.AddQueue(q); //si ya exite la cola, hago update?
                    }
                }
            });

            Receive <MessageMemberLogin>(mlin =>
            {
                //Mensaje que proviene del ActorMemberLoginService, aca creo un nuevo member, cuando me llegan los QMemberAdd creo los
                //QueueMember en base a este objeto. El member quue creo aca tambien recibe mensajes del stateprovider
                Member member = new Member()
                {
                    Id = mlin.MemberId, Name = mlin.Name, Contact = mlin.Contact, Password = mlin.Password, DeviceId = mlin.DeviceId
                };
                queueSystem.MemberCache.Add(member);
                queueSystem.MemberCache.MemberLogin(member);

                actorQueueLog.Tell(new QLMemberLogin()
                {
                    Source = mlin.From, Channel = mlin.RequestId, MemberId = mlin.MemberId, Name = mlin.Name, DeviceId = mlin.DeviceId
                });
            });

            Receive <MessageMemberLogoff>(mlof =>
            {
                //Mensaje que proviene del ActorMemberLoginService
                queueSystem.MemberCache.MemberLogoff(mlof.MemberId);
                Member member = queueSystem.MemberCache.Remove(mlof.MemberId);

                actorQueueLog.Tell(new QLMemberLogoff()
                {
                    Source = mlof.From, Channel = mlof.RequestId, MemberId = mlof.MemberId, LoggedInTime = member.LoginElapsedTime
                });
            });

            Receive <MessageQMemberPause>(mpau =>
            {
                queueSystem.MemberCache.MemberPause(mpau.MemberId, mpau.PauseReason, mpau.PauseReason);
                actorQueueLog.Tell(new QLMemberPause()
                {
                    Source = mpau.From, Channel = mpau.RequestId, MemberId = mpau.MemberId, Reason = mpau.PauseReason
                });
            });

            Receive <MessageQMemberUnpause>(munpau =>
            {
                Member member = queueSystem.MemberCache.GetMemberById(munpau.MemberId);
                if (member.IsPaused)
                {
                    member = queueSystem.MemberCache.MemberUnPause(munpau.MemberId);
                    actorQueueLog.Tell(new QLMemberUnpause()
                    {
                        Source = munpau.From, Channel = munpau.RequestId, MemberId = munpau.MemberId, PausedTime = member.PauseElapsedTime
                    });
                }
            });

            Receive <MessageQMemberAdd>(memberQueues =>
            {
                //Mensaje que proviene del ActorMemberLoginService, posee una lista de los id de las colas de un miembro
                //me parece que esta logica deberia estar dentro del queue sistem, aca no.
                foreach (string queueId in memberQueues.QueuesId)
                {
                    // mmmm... es correcto aca recuperar el member,crear un queue member y recien ahi agregarlo?
                    Member member = queueSystem.MemberCache.GetMemberById(memberQueues.MemberId);
                    if (member != null)
                    {
                        QueueMember qm = new QueueMember(member);
                        queueSystem.QueueCache.GetQueue(queueId).AddQueueMember(qm);
                        actorQueueLog.Tell(new QLMemberAdd()
                        {
                            Source = memberQueues.From, Channel = memberQueues.RequestId, QueueId = queueId, MemberId = member.Id
                        });
                    }
                }
            });

            Receive <MessageQMemberRemove>(memberQueues =>
            {
                //Mensaje que proviene del ActorMemberLoginService, posee una lista de los id de las colas de un miembro
                //me parece que esta logica deberia estar dentro del queue sistem, aca no.
                foreach (string queueId in memberQueues.QueuesId)
                {
                    // mmmm... es correcto aca recuperar el member,crear un queue member y recien ahi agregarlo?
                    Member member = queueSystem.MemberCache.GetMemberById(memberQueues.MemberId);
                    if (member != null)
                    {
                        QueueMember qm = new QueueMember(member);
                        queueSystem.QueueCache.GetQueue(queueId).RemoveQueueMember(qm);
                        actorQueueLog.Tell(new QLMemberRemove()
                        {
                            Source = memberQueues.From, Channel = memberQueues.RequestId, QueueId = queueId, MemberId = member.Id
                        });
                    }
                }
            });
            // Ejemplo de filtro de mensaje: Receive<String>(s => s.Equals("Start"), (s) => { proxyClient.Connect(); }); //ejemplito
            //Es estado del del sipositivo de
            Receive <MessageDeviceStateChanged>(dsc =>
            {
                Member member = queueSystem.MemberCache.GetMemberById(dsc.MemberId);
                //verifico que sea del mismo dispositivo
                if (dsc.DeviceId == member.DeviceId)
                {
                    if (!String.IsNullOrEmpty(dsc.Contact))
                    {
                        member.Contact = dsc.Contact;
                    }

                    member.DeviceIsInUse    = dsc.IsInUse;
                    member.EndpointIsOfline = dsc.IsOffline;
                    Log.Logger.Debug("CALL DIST: member STATE changed, Contact: " + member.Contact + ", IsInUse: " + member.DeviceIsInUse);
                }
            });
            Receive <MessageNewCall>(nc =>
            {
                Queue queue = queueSystem.QueueCache.GetQueue(nc.QueueId);
                Call call   = new Call()
                {
                    CallHandlerId = nc.CallHandlerId, ChannelId = nc.ChannelId
                };
                QueueMember queueMember = null;
                if (queue != null)
                {
                    queueMember = queue.AddCall(call); //agrega la llamada y si hay un qm para atenderla lo devuelve
                    actorQueueLog.Tell(new QLEnterQueue()
                    {
                        Source = nc.From, QueueId = queue.Id, Channel = call.ChannelId
                    });
                }
                Sender.Tell(new MessageAnswerCall()
                {
                    CallHandlerId = nc.CallHandlerId, MediaType = queue.MediaType, Media = queue.Media
                });
                if (queueMember == null)
                {
                    //guardo en el call el uid del sender
                    call.SenderUid = Sender.Path.Uid;
                    //guardo una referencia al sender si no la tengo
                    if (!callSenders.ContainsKey(Sender.Path.Uid))
                    {
                        callSenders.Add(Sender.Path.Uid, Sender);
                    }
                    //le aviso al sender que su llamada quedó encolada hasta que se libere un member
                    Sender.Tell(new MessageCallQueued()
                    {
                        CallHandlerId = nc.CallHandlerId
                    });
                }
                else
                {
                    call.IsDispatching = true;
                    call.QueueMember   = queueMember;
                    Sender.Tell(new MessageCallTo()
                    {
                        CallHandlerId = nc.CallHandlerId, Destination = queueMember.Member.Contact
                    });
                }
            });

            Receive <MessageCallerExitWithTimeOut>(cewto =>
            {
                Queue queue = queueSystem.QueueCache.GetQueue(cewto.QueueId);
                if (queue != null)
                {
                    Call call = queue.calls.GetCallById(cewto.CallHandlerId);
                    if (call != null)
                    {
                        if (call.QueueMember != null)
                        {
                            call.IsDispatching = false;
                            call.QueueMember.Member.IsAvailable = true;
                            call.QueueMember = null;
                        }
                        queue.calls.RemoveCall(call);
                        actorQueueLog.Tell(new QLCallExitWithTimeOut()
                        {
                            Source  = cewto.From,
                            QueueId = queue.Id,
                            Channel = call.ChannelId,
                            TimeOut = cewto.TimeOut
                        });
                    }
                }
            });

            Receive <MessageCallToFailed>(ctf =>
            {
                //Busco otro member
                Log.Logger.Debug("CALL DIST: callto failed with code: " + ctf.Code.ToString() + " Reason: " + ctf.Reason);
                Queue queue = queueSystem.QueueCache.GetQueue(ctf.QueueId);
                if (queue != null)
                {
                    Call call = queue.calls.GetCallById(ctf.CallHandlerId);
                    if (call != null)
                    {
                        call.QueueMember.Member.IsAvailable = true;
                        QueueMember queueMember             = queue.members.NextAvailable(queue.WrapupTime);
                        if (queueMember != null)
                        {
                            call.QueueMember = queueMember;
                            Sender.Tell(new MessageCallTo()
                            {
                                CallHandlerId = ctf.CallHandlerId, Destination = queueMember.Member.Contact
                            });
                            actorQueueLog.Tell(new QLRingNoAnswer()
                            {
                                Source      = ctf.From,
                                QueueId     = queue.Id,
                                Channel     = call.ChannelId,
                                MemberId    = call.QueueMember.Id,
                                Code        = ctf.Code,
                                Reason      = ctf.Reason,
                                RingingTime = ctf.RingingTime
                            });
                        }
                    }
                }
            });
            Receive <MessageCallToSuccess>(cts =>
            {
                Log.Logger.Debug("CALL DIST: callto success");
                Queue queue = queueSystem.QueueCache.GetQueue(cts.QueueId);
                Call call;
                if (queue != null)
                {
                    call = queue.calls.GetCallById(cts.CallHandlerId);
                    if (call != null)
                    {
                        call.IsDispatching = false;
                        call.Connected     = true;
                        actorQueueLog.Tell(new QLConnect()
                        {
                            Source   = cts.From,
                            QueueId  = queue.Id,
                            Channel  = call.ChannelId,
                            MemberId = call.QueueMember.Id,
                            HoldTime = cts.HoldTime
                        });
                    }
                }
            });
            Receive <MessageCallerHangup>(chup =>
            {
                //si caller hangup termino toda la llamada?, tal vez comportamiento configurable?
                Log.Logger.Debug("CALL DIST: Caller Hangup");
                Queue queue = queueSystem.QueueCache.GetQueue(chup.QueueId);
                if (queue != null)
                {
                    Call call = queue.calls.RemoveCall(chup.CallHandlerId);
                    QueueMember queueMember = call.QueueMember;
                    if (queueMember != null)
                    {
                        queueMember.MarkLastCallTime();
                        queueMember.Member.IsAvailable = true;
                    }
                    if (call.Connected == false)
                    {
                        actorQueueLog.Tell(new QLAbandon()
                        {
                            Source      = chup.From,
                            QueueId     = queue.Id,
                            Channel     = call.ChannelId,
                            WaitingTime = chup.WatingTime
                        });
                    }
                    else
                    {
                        actorQueueLog.Tell(new QLCallerHangUp()
                        {
                            Source      = chup.From,
                            QueueId     = queue.Id,
                            Channel     = call.ChannelId,
                            MemberId    = call.QueueMember.Id,
                            WatingTime  = chup.WatingTime,
                            HoldingTime = chup.HoldingTime,
                            TalkingTime = chup.TalkingTime
                        });
                    }
                }
            });

            Receive <MessageAgentHangup>(ahup =>
            {
                //Si agent hangup hago que la llamada del caller siga en el dialplan?
                Log.Logger.Debug("CALL DIST: Agent Hangup");
                Queue queue = queueSystem.QueueCache.GetQueue(ahup.QueueId);
                if (queue != null)
                {
                    Call call = queue.calls.RemoveCall(ahup.CallHandlerId);
                    QueueMember queueMember;
                    if (call != null)
                    {
                        queueMember = call.QueueMember;

                        if (queueMember != null)
                        {
                            queueMember.MarkLastCallTime();
                            queueMember.Member.IsAvailable = true;
                            actorQueueLog.Tell(new QLAgentHangUp()
                            {
                                Source      = ahup.From,
                                QueueId     = queue.Id,
                                Channel     = call.ChannelId,
                                MemberId    = call.QueueMember.Id,
                                WatingTime  = ahup.WatingTime,
                                HoldingTime = ahup.HoldingTime,
                                TalkingTime = ahup.TalkingTime
                            });
                        }
                    }
                }
            });

            Receive <MessageCallTransfer>(ctrans =>
            {
                Log.Logger.Debug("CALL DIST: Call Trasnfer: dst: " + ctrans.TargetName);
                Queue queue = queueSystem.QueueCache.GetQueue(ctrans.QueueId);
                if (queue != null)
                {
                    Call call = queue.calls.RemoveCall(ctrans.CallHandlerId);
                    QueueMember queueMember = call.QueueMember;
                    if (queueMember != null)
                    {
                        queueMember.MarkLastCallTime();
                        queueMember.Member.IsAvailable = true;
                        actorQueueLog.Tell(new QLTransfer()
                        {
                            Source            = ctrans.From,
                            QueueId           = queue.Id,
                            Channel           = call.ChannelId,
                            MemberId          = call.QueueMember.Id,
                            TargetChannelId   = ctrans.TargetId,
                            TargetChannelName = ctrans.TargetName,
                            WatingTime        = ctrans.WatingTime,
                            HoldingTime       = ctrans.HoldingTime,
                            TalkingTime       = ctrans.TalkingTime
                        });
                    }
                }
            });

            Receive <MessageCallHold>(cho =>
            {
                Queue queue = queueSystem.QueueCache.GetQueue(cho.QueueId);
                if (queue != null)
                {
                    Call call = queue.calls.GetCallById(cho.CallHandlerId);
                    QueueMember queueMember = call.QueueMember;
                    if (queueMember != null)
                    {
                        actorQueueLog.Tell(new QLCallHoldStart()
                        {
                            Source   = cho.From,
                            QueueId  = queue.Id,
                            Channel  = call.ChannelId,
                            MemberId = call.QueueMember.Id
                        });
                    }
                }
            });

            Receive <MessageCallUnHold>(cuho =>
            {
                Queue queue = queueSystem.QueueCache.GetQueue(cuho.QueueId);
                if (queue != null)
                {
                    Call call = queue.calls.GetCallById(cuho.CallHandlerId);
                    QueueMember queueMember = call.QueueMember;
                    if (queueMember != null)
                    {
                        actorQueueLog.Tell(new QLCallHoldStop()
                        {
                            Source   = cuho.From,
                            QueueId  = queue.Id,
                            Channel  = call.ChannelId,
                            MemberId = call.QueueMember.Id,
                            HoldTime = cuho.HoldTime
                        });
                    }
                }
            });

            Receive <MessageCheckReadyMember>(rdymem =>
            {
                //Log.Logger.Debug("CALL DIST: Check Ready Member: ");
                foreach (Queue queue in queueSystem.QueueCache.QueueList)
                {
                    if (queue != null)
                    {
                        Call call = queue.CheckPendingCalls();
                        QueueMember queueMember = null;

                        if (call != null)
                        {
                            queueMember = call.QueueMember;
                        }

                        if (queueMember != null)
                        {
                            //guardo una referencia al sender si no la tengo
                            if (callSenders.ContainsKey(call.SenderUid))
                            {
                                call.IsDispatching = true;
                                callSenders[call.SenderUid].Tell(new MessageCallTo()
                                {
                                    CallHandlerId = call.CallHandlerId, Destination = queueMember.Member.Contact
                                });
                            }
                        }
                    }
                }
            });

            #region "MANEJO DE CONSULTAS"

            /**************** MANEJO DE CONSULTAS *******************/

            Receive <CMDListQueues>(cmdlq =>
            {
                RESQueueList rql = new RESQueueList();

                foreach (Queue queue in queueSystem.QueueCache.QueueList)
                {
                    RESQueue rq = new RESQueue()
                    {
                        Id        = queue.Id,
                        MediaType = queue.MediaType
                    };

                    foreach (Call call in queue.calls.Calls)
                    {
                        RESCall rc = new RESCall()
                        {
                            CallHandlerId   = call.CallHandlerId,
                            ChannelId       = call.ChannelId,
                            QueueMemberId   = call.QueueMember != null ? call.QueueMember.Member.Id : null,
                            QueueMemberName = call.QueueMember != null ? call.QueueMember.Member.Name : null,
                            StartTime       = call.StartTime,
                            IsDispatching   = call.IsDispatching,
                            Connected       = call.Connected
                        };
                        rq.Calls.Add(rc);
                    }

                    foreach (QueueMember qMember in queue.members.Members)
                    {
                        RESMember rm = new RESMember()
                        {
                            Id          = qMember.Member.Id,
                            Contact     = qMember.Member.Contact,
                            DeviceId    = qMember.Member.DeviceId,
                            Name        = qMember.Member.Name,
                            IsPaused    = qMember.Member.IsPaused,
                            IsLogedIn   = qMember.Member.IsLogedIn,
                            PauseCode   = qMember.Member.PauseCode,
                            PauseReason = qMember.Member.PauseReason
                        };
                        rq.Members.Add(rm);
                    }

                    rql.Queues.Add(rq);
                }
                Sender.Tell(rql, Self);
            });

            #endregion
        }