上一篇文章 讨论了 invite请求最终 走到 dialplan,走到拨号方案后 具体做什么动作由用户决定,对于呼叫中心应用,队列是必不可少的功能,本篇文档分析一下主叫打进系统,走到dialplan后 进队列,呼叫坐席。。
一切从队列开始。。。。
queue(nama,timout,tT,,.),
queue_exec为队列入口函数。首先解析 队列参数。
AST_DECLARE_APP_ARGS(args,
AST_APP_ARG(queuename);
AST_APP_ARG(options);
AST_APP_ARG(url);
AST_APP_ARG(announceoverride);
AST_APP_ARG(queuetimeoutstr);
AST_APP_ARG(agi);
AST_APP_ARG(macro);
AST_APP_ARG(gosub);
AST_APP_ARG(rule);
AST_APP_ARG(position);
这里 1.8版本增加了参数 position
此参数指定 主叫进入队列后在所有主叫中的排队位置,为1,则此客户优先级最高,优先接听,,这是个参数在队列内有很多等待电话时有用。
此参数跟 QUEUE_PRIO 类似,但position更灵活。。。
队列参数解析完毕 调用 join_queue 进入队列。。。同时指定进入队列失败原因。。。设置 QUEUESTATUS.
join_queue内部。首先调用 load_realtime_queue,加载队列坐席信息。。。
load_realtime_queue 内部,首先根据 队列名字 在内存中查找 队列是否存在,有,则返回在内存中的位置,否则为NULL
/* Find the queue in the in-core list first. */
q = ao2_t_find(queues, &tmpq, OBJ_POINTER, "Look for queue in memory first");
这里ao2_t_find为hash查找,速度应该比链表快多了,这是1.6,1.8版本提供的。
if (!q || q->realtime)
如果没找到 ,或者找到了&&队列是realtime(数据库保存队列)的,则,调用ast_load_realtime,从数据库中加载队列信息。
所以,对于realtime队列,不管找不找到,都会执行数据库加载动作。
queue_vars = ast_load_realtime("queues", "name", queuename, SENTINEL);
if (queue_vars) {
member_config = ast_load_realtime_multientry("queue_members", "interface LIKE", "%", "queue_name", queuename, SENTINEL);
if (!member_config) {
ast_log(LOG_ERROR, "no queue_members defined in your config (extconfig.conf)./n");
ast_variables_destroy(queue_vars);
return NULL;
}
}
if (q) {
prev_weight = q->weight ? 1 : 0;
}
首先根据队列名字加载队列,如果数据库中存在此队列,则加载此队列的坐席(queue_member表),没有坐席会则函数退出。这里做这两个步骤的目的是做一些溢出处理,如数据库没有队列,或队列无坐席等。
接下来 ,如果内存中存在此队列,则设置队列优先级。
然后调用 find_queue_by_name_rt 函数,此函数很重要,他的功能为 做数据库信息与内存的同步。。。返回全新的队列 到q
q = find_queue_by_name_rt(queuename, queue_vars, member_config);
*****
queue_vars 保存的是 数据库队列信息,member_config 保存的是 数据库内此队列的坐席信息。
下面分析一下find_queue_by_name_rt
首先处理 不是 realtime的队列。接下来处理realtime队列。
/* Check if queue is defined in realtime. */
if (!queue_vars) {
1。根据数据库中是否存在队列判断是否为realtime队列,,这里,如果数据库中队列已经没了,但内存中该队列还存在(不是queue.conf静态配置的队列),,此时,设置队列死亡。q->dead = 1;。实际就是在内存中删除,
2。数据库中存在,内存中不存在。创建。。。
alloc_queue 分配队列内存。。。同时指定析构函数。
clear_queue,清理队列,初始化队列,首先设置队列策略,找不到就设置默认ringall,这里这么早设置队列策略的原因为lineer策略依赖于
此设置,因为下面为初始化坐席到内存中时要用到策略。接下来把此队列放到全局队列容器中queues_t_link(queues, q, "Add queue to container");
接下来调用 init_queue 初始化队列默认值。这里,如果内存中已经存在,则也重置队列参数。原因是在与数据库同步。
包括 队列参数queue.conf 中 autopause,timeoutpriority 等的初始化。。坐席的分配。。。
q->dead = 0;
q->retry = DEFAULT_RETRY;
q->timeout = DEFAULT_TIMEOUT;
q->maxlen = 0;
q->announcefrequency = 0;
q->minannouncefrequency = DEFAULT_MIN_ANNOUNCE_FREQUENCY;
q->announceholdtime = 1;
q->announcepositionlimit = 10; /* Default 10 positions */
q->announceposition = ANNOUNCEPOSITION_YES; /* Default yes */
q->roundingseconds = 0; /* Default - don't announce seconds */
q->servicelevel = 0;
q->ringinuse = 1;
q->setinterfacevar = 0;
q->setqueuevar = 0;
q->setqueueentryvar = 0;
q->autofill = autofill_default;
q->montype = montype_default;
q->monfmt[0] = '/0';
q->reportholdtime = 0;
q->wrapuptime = 0;
q->penaltymemberslimit = 0;
q->joinempty = 0;
q->leavewhenempty = 0;
q->memberdelay = 0;
q->maskmemberstatus = 0;
q->eventwhencalled = 0;
q->weight = 0;
q->timeoutrestart = 0;
q->periodicannouncefrequency = 0;
q->randomperiodicannou
4424




被折叠的 条评论
为什么被折叠?



