1. 宁卫免费PBX中的排队机空闲分机搜询策略:
  2. 宁卫通信
  3. 新闻动态
  4. 宁卫新闻
  5. 宁卫免费PBX中的排队机空闲分机搜询策略

宁卫免费PBX中的排队机空闲分机搜询策略

      在以前,我们是在c代码中使用了若干条命令去查询一个空闲的座席,但是发现那样存在若干问题:

1. 效率慢。

2. 在大并发情况下,锁加的多就会影响体验,锁加少了,会出现话机冲突。

3. c语言中改逻辑性的东西,挺头痛。所以把其改为PostgreSQL的function,即存储过程来使用,因为这部分都是离线部署的,所以触发器和存储过程是任一用户都可以看到的,故而把源代码分享出来。

       表名和表结构就不列出来了,在数据库中都有,只列出存储过程的代码:

drop function get_group_idle_ext_first;--get_group_idle_ext_first用于查找第一个空闲的座席分机--p_use_multi_domain  是不是使用多租户--p_callin_number  呼入号码--p_group_number   组名或组短号,但可以带domain--p_transfer_times  呼转次数,第一次会考虑以前是谁接的,那么本次优先他--p_use_agent_status 是否要使用座席状态,如置忙、置闲,迁入迁出(上线下线)等,1为需要,0为不需要,放在这里,也可以允许使用者自己手工更改CREATE FUNCTION get_group_idle_ext_first( IN p_use_multi_domain BOOLEAN, IN p_callin_number TEXT, IN p_group_number TEXT, IN p_transfer_times int, IN p_use_agent_status int)RETURNS TABLE( myext text, mytimeout INT, mypassed BOOLEAN) LANGUAGE 'plpgsql' COST 100 VOLATILE PARALLEL UNSAFEAS $BODY$DECLARE f_mode int;f_timeout int;f_domain TEXT;f_group_number TEXT;f_position int;f_sql TEXT;f_c_split TEXT;f_use_agent_status int;--------r_passed BOOLEAN;r_ext Text;r_timeout int;----v_record  RECORD;BEGIN r_passed := false; f_c_split := '@'; if (p_use_multi_domain =true) then f_group_number := p_group_number; f_position := strpos(f_group_number,'@'); --postition(f_c_split in f_group_number);     if (f_position = 0then f_group_number := p_group_number; f_domain := 'default'; else f_group_number := substring(p_group_number from 1 for f_position-1); f_domain := substring(p_group_number from f_position+1 for char_length(p_group_number)-f_position ); end if;  else f_group_number := p_group_number; f_domain := 'default'; end if; f_mode := -1;   if (p_use_agent_status =1then f_use_agent_status :=1;  else f_use_agent_status :=0; end if;  raise notice 'group_number is %',f_group_number; raise notice 'domain is %',f_domain; ---------------------------------  if (p_use_multi_domain = true) then f_sql := 'select a.queue_mode,a.group_callout_timeout from nway_ext_group a, nway_fs_domains b where a.group_number=''' || f_group_number || ''' and a.domain_id=b.id and b.domain_name=''' || f_domain || ''';';  else f_sql := 'select queue_mode  ,group_callout_timeout  from nway_ext_group  where  group_number=''' || f_group_number || ''';'; end if;   raise notice 'group sql:%',f_sql;  EXECUTE f_sql INTO f_mode,f_timeout;  raise notice 'mode:%, timeout:%',f_mode,f_timeout; if (f_mode is NULL) then raise notice 'data is null'; r_timeout := -1; r_ext := 'error:not found group'; else if (f_mode < 0) then --return r_passed; r_timeout := -1; r_ext := 'mode not support'; else --执行后续 if (f_timeout is NULL) then r_timeout = 15; else r_timeout = f_timeout; end if;  if (f_mode >2 and p_transfer_times = 0) then if (p_use_multi_domain = true) then if (f_use_agent_status =1) then f_sql := 'SELECT extension_number  FROM nway_extension  where reg_state=''reged'' and agent_status=''idle'' and ' || ' call_state=''ready'' and extension_number  = ' ||  ' (select agent_number from nway_call_remember where call_number=''' || p_callin_number ||  ''' and  group_number=''' || f_group_number || ''' and domain_name=''' || f_domain || ''' order by insert_time desc limit 1 );'; else f_sql := 'SELECT extension_number  FROM nway_extension  where reg_state=''reged''    ' || ' and call_state=''ready'' and extension_number  = ' ||  ' (select agent_number from nway_call_remember where call_number=''' || p_callin_number ||  ''' and  group_number=''' || f_group_number || ''' and domain_name=''' || f_domain || ''' order by insert_time desc limit 1 );'; end if;  else if (f_use_agent_status =1) then f_sql := 'SELECT extension_number  FROM nway_extension  where reg_state=''reged'' and agent_status=''idle'' and call_state=''ready''' ||  ' and extension_number  = (select agent_number from nway_call_remember where call_number=''' ||p_callin_number ||  ''' and group_number=''' || f_group_number || ''' order by insert_time desc limit 1 );'; else f_sql := 'SELECT extension_number  FROM nway_extension  where reg_state=''reged'' and   call_state=''ready''' ||  ' and extension_number  = (select agent_number from nway_call_remember where call_number=''' ||p_callin_number ||  ''' and group_number=''' || f_group_number || ''' order by insert_time desc limit 1 );'; end if;  end if; raise notice 'last agent sql:%',f_sql;  EXECUTE f_sql INTO r_ext; end if; ------  if (r_ext is NULL OR char_length(r_ext) <2) then  RAISE NOTICE 'search idle agent from talbe:%',p_callin_number; if (p_use_multi_domain = true) then if (f_use_agent_status =1) then if (f_mode=3 OR f_mode = 0) then f_sql := 'select c.extension_number from nway_extension c,nway_ext_group e,nway_fs_domains s where (c.reg_state=''reged'' OR c.reg_state=''REGED'')' || ' and (c.call_state=''ready'' OR c.call_state=''READY'') and (c.agent_state=''up'' OR c.agent_state=''UP'') and (c.agent_status=''ready'' OR c.agent_status=''idle'')' || ' and s.id=e.domain_id and s.domain_name=''' || f_domain || '''  and (e.group_number=''' ||f_group_number || ''') and '|| ' (c.extension_number in ( select m.ext from nway_ext_group_map m, nway_ext_group n,nway_fs_domains p  where n.group_number=''' || f_group_number ||  ''' and n.id =m.ext_group_id and n.domain_id=p.id and p.domain_name=''' || f_domain || ''' )) and (extract(epoch FROM (now()-c.last_state_change_time)) >1 ) order by c.extension_number limit 1;'; end if; if (f_mode=1 OR f_mode = 4) then f_sql := 'select c.extension_number from nway_extension c,nway_ext_group e,nway_fs_domains s where (c.reg_state=''reged'' OR c.reg_state=''REGED'')'|| ' and (c.call_state=''ready'' OR c.call_state=''READY'') and (c.agent_state=''up'' OR c.agent_state=''UP'') and (c.agent_status=''ready'' OR c.agent_status=''idle'')'|| ' and s.id=e.domain_id and s.domain_name=''' || f_domain ||'''  and (e.group_number=''' ||f_group_number || ''') and (c.extension_number in ' || ' ( select m.ext from nway_ext_group_map  m, nway_ext_group n,nway_fs_domains p  where n.group_number=''' || f_group_number ||  ''' and n.id =m.ext_group_id and n.domain_id=p.id and p.domain_name=''' || f_domain || ''')) and (extract(epoch FROM (now()-c.last_state_change_time)) >1 ) order by random() limit 1;'; end if; if (f_mode = 2 OR f_mode =5) then f_sql := 'select c.extension_number from nway_extension c,nway_ext_group e,nway_fs_domains s where (c.reg_state=''reged'' OR c.reg_state=''REGED'') and' || ' (c.call_state=''ready'' OR c.call_state=''READY'') and (c.agent_state=''up'' OR c.agent_state=''UP'') and (c.agent_status=''ready'' OR c.agent_status=''idle'')'|| ' and s.id=e.domain_id and s.domain_name=''' || f_domain ||'''  and (c.extension_number >e.current_ext_number) and (e.group_number=''' || f_group_number || ''') and (c.extension_number in ( select m.ext from nway_ext_group_map  m, nway_ext_group n,nway_fs_domains p  where n.group_number=''' || f_group_number ||  ''' and n.id =m.ext_group_id and n.domain_id=p.id and p.domain_name=''' || f_domain || ''' )) and (extract(epoch FROM (now()-c.last_state_change_time)) >1 ) order by c.extension_number limit 1;';  end if;  else if (f_mode=3 OR f_mode = 0) then f_sql := 'select c.extension_number from nway_extension c,nway_ext_group e,nway_fs_domains s where (c.reg_state=''reged'' OR c.reg_state=''REGED'')' || ' and (c.call_state=''ready'' OR c.call_state=''READY'')' || ' and s.id=e.domain_id and s.domain_name=''' || f_domain || '''  and (e.group_number=''' ||f_group_number || ''') and '|| ' (c.extension_number in ( select m.ext from nway_ext_group_map m, nway_ext_group n,nway_fs_domains p  where n.group_number=''' || f_group_number ||  ''' and n.id =m.ext_group_id and n.domain_id=p.id and p.domain_name=''' || f_domain || ''' )) and (extract(epoch FROM (now()-c.last_state_change_time)) >1 ) order by c.extension_number limit 1;'; end if; if (f_mode=1 OR f_mode = 4) then f_sql := 'select c.extension_number from nway_extension c,nway_ext_group e,nway_fs_domains s where (c.reg_state=''reged'' OR c.reg_state=''REGED'')'|| ' and (c.call_state=''ready'' OR c.call_state=''READY'') '|| ' and s.id=e.domain_id and s.domain_name=''' || f_domain ||'''  and (e.group_number=''' ||f_group_number || ''') and (c.extension_number in ' || ' ( select m.ext from nway_ext_group_map  m, nway_ext_group n,nway_fs_domains p  where n.group_number=''' || f_group_number ||  ''' and n.id =m.ext_group_id and n.domain_id=p.id and p.domain_name=''' || f_domain || ''')) and (extract(epoch FROM (now()-c.last_state_change_time)) >1 ) order by random() limit 1;'; end if; if (f_mode = 2 OR f_mode =5) then f_sql := 'select c.extension_number from nway_extension c,nway_ext_group e,nway_fs_domains s where (c.reg_state=''reged'' OR c.reg_state=''REGED'') and' || ' (c.call_state=''ready'' OR c.call_state=''READY'') '|| ' and s.id=e.domain_id and s.domain_name=''' || f_domain ||'''  and (c.extension_number >e.current_ext_number) and (e.group_number=''' || f_group_number || ''') and (c.extension_number in ( select m.ext from nway_ext_group_map  m, nway_ext_group n,nway_fs_domains p  where n.group_number=''' || f_group_number ||  ''' and n.id =m.ext_group_id and n.domain_id=p.id and p.domain_name=''' || f_domain || ''' )) and (extract(epoch FROM (now()-c.last_state_change_time)) >1 ) order by c.extension_number limit 1;';  end if;  end if; else if (f_use_agent_status =1) then if (f_mode=3 OR f_mode = 0) then f_sql := 'select c.extension_number from nway_extension c,nway_ext_group e where (c.reg_state=''reged'' OR c.reg_state=''REGED'') and (c.call_state=''ready'' OR c.call_state=''READY'')'|| ' and (c.agent_state=''up'' OR c.agent_state=''UP'') and (c.agent_status=''ready'' OR c.agent_status=''idle'')  and (e.group_number=''' ||f_group_number ||  ''') and (c.extension_number in ( select ext from nway_ext_group_map where ext_group_number=''' || f_group_number ||  ''')) and (extract(epoch FROM (now()-c.last_state_change_time)) >1 ) order by c.extension_number limit 1; '; end if; if (f_mode=1 OR f_mode = 4) then f_sql := 'select c.extension_number from nway_extension c,nway_ext_group e where (c.reg_state=''reged'' OR c.reg_state=''REGED'') and (c.call_state=''ready'' OR c.call_state=''READY'') '|| ' and (c.agent_state=''up'' OR c.agent_state=''UP'') and (c.agent_status=''ready'' OR c.agent_status=''idle'') and (e.group_number=''' ||f_group_number ||  ''') and (c.extension_number in ( select ext from nway_ext_group_map where ext_group_number=''' || f_group_number ||  ''')) and (extract(epoch FROM (now()-c.last_state_change_time)) >1 ) order by random() limit 1; '; end if; if (f_mode = 2 OR f_mode =5) then --from e.current_ext_number f_sql := 'select c.extension_number from nway_extension c,nway_ext_group e where (c.reg_state=''reged'' OR c.reg_state=''REGED'') and (c.call_state=''ready'' OR c.call_state=''READY'')' || ' and (c.agent_state=''up'' OR c.agent_state=''UP'') and (c.agent_status=''ready'' OR c.agent_status=''idle'') and (c.extension_number >e.current_ext_number)'|| ' and (e.group_number=''' ||f_group_number ''') and (c.extension_number in ( select ext from nway_ext_group_map where ext_group_number=''' || f_group_number || ''')) and '|| '(extract(epoch FROM (now()-c.last_state_change_time)) >1 ) order by c.extension_number limit 1; ';  end if;  else if (f_mode=3 OR f_mode = 0) then f_sql := 'select c.extension_number from nway_extension c,nway_ext_group e where (c.reg_state=''reged'' OR c.reg_state=''REGED'') and (c.call_state=''ready'' OR c.call_state=''READY'')'|| '    and (e.group_number=''' ||f_group_number ||  ''') and (c.extension_number in ( select ext from nway_ext_group_map where ext_group_number=''' || f_group_number ||  ''')) and (extract(epoch FROM (now()-c.last_state_change_time)) >1 ) order by c.extension_number limit 1; '; end if; if (f_mode=1 OR f_mode = 4) then f_sql := 'select c.extension_number from nway_extension c,nway_ext_group e where (c.reg_state=''reged'' OR c.reg_state=''REGED'') and (c.call_state=''ready'' OR c.call_state=''READY'') '|| '   and (e.group_number=''' ||f_group_number ||  ''') and (c.extension_number in ( select ext from nway_ext_group_map where ext_group_number=''' || f_group_number ||  ''')) and (extract(epoch FROM (now()-c.last_state_change_time)) >1 ) order by random() limit 1; '; end if; if (f_mode = 2 OR f_mode =5) then --from e.current_ext_number f_sql := 'select c.extension_number from nway_extension c,nway_ext_group e where (c.reg_state=''reged'' OR c.reg_state=''REGED'') and (c.call_state=''ready'' OR c.call_state=''READY'')' || '  and (c.extension_number >e.current_ext_number)'|| ' and (e.group_number=''' ||f_group_number ''') and (c.extension_number in ( select ext from nway_ext_group_map where ext_group_number=''' || f_group_number || ''')) and '|| '(extract(epoch FROM (now()-c.last_state_change_time)) >1 ) order by c.extension_number limit 1; ';  end if;  end if; end if; raise notice 'agent sql:%',f_sql; EXECUTE f_sql INTO r_ext;  if (r_ext is NULL) then r_passed := false; r_ext := ''; raise notice 'not found idle extension'; r_timeout=0;          if (f_mode = 2 OR f_mode =5then if (p_use_multi_domain = true) then f_sql := 'select c.extension_number from nway_extension c,nway_ext_group e,nway_fs_domains s where (c.reg_state=''reged'' OR c.reg_state=''REGED'') and ' ||  ' (c.call_state=''ready'' OR c.call_state=''READY'') and (c.seat_state=''up'' OR c.seat_state=''UP'') and (c.seat_status=''ready'' OR c.seat_status=''idle'') ' || ' and s.id=e.domain_id and s.domain_name=''' || f_domain || '''  and (e.group_number=''' || f_group_number || ''') and (c.extension_number in (select m.ext from nway_ext_group_map  m, nway_ext_group n,nway_fs_domains p  where n.group_number=''' || f_group_number || ''' and n.id =m.ext_group_id and n.domain_id=p.id and p.domain_name=''' || f_domain || ''' )) order by c.extension_number limit 1;'; else f_sql := 'select c.extension_number from nway_extension c,nway_ext_group e  where (c.reg_state=''reged'' OR c.reg_state=''REGED'') and '|| ' (c.call_state=''ready'' OR c.call_state=''READY'') and (c.seat_state=''up'' OR c.seat_state=''UP'') and (c.seat_status=''ready'' OR c.seat_status=''idle'') '|| ' and (e.group_number=''' || f_group_number || ''') and (c.extension_number in ( select ext from nway_ext_group_map where ext_group_number=''' || f_group_number || ''')) order by c.extension_number limit 1;'; end if;  raise notice 'mode 2or5 repeat sql:%',f_sql; EXECUTE f_sql INTO r_ext; if (r_ext is NULL ) then r_passed = false; else r_passed = true; end if; end if; else raise notice 'found idle extension'; r_passed = true; end if;  else  r_passed := true; end if; end if;    end if; if (r_passed = true) then   if (p_use_multi_domain = true) then f_sql := 'update nway_extension set call_state=''callout'',last_state_change_time=now() where extension_number ='''|| r_ext ||''' and domain_id=(select id from nway_fs_domwains where domain_name='''|| f_domain || ''');'; else f_sql :='update nway_extension set call_state=''callout'',last_state_change_time=now() where extension_number ='''|| r_ext ||''';'; end if; raise notice 'found ext:% !!! and set it callout sql:%',r_ext,f_sql; EXECUTE f_sql;   if (p_use_multi_domain = true) then f_sql := 'update nway_ext_group set current_ext_number=''' || r_ext|| ''' where group_number =''' || f_group_number || ''' and domain_id in (select id from nway_fs_domains where domain_name='''|| f_domain || ''');'; else f_sql :='update nway_ext_group set current_ext_number=''' || r_ext|| ''' where group_number =''' || f_group_number || ''';'; end if; raise notice 'set ext:% is current using extension for group sql:%',r_ext,f_sql; EXECUTE f_sql;  if (p_use_multi_domain = true ) then myext := r_ext || '@' || f_domain; else myext := r_ext; end if; else myext := ''; end if; mypassed := r_passed; mytimeout := r_timeout; return query select myext,mytimeout,mypassed; END;$BODY$;    select public.get_group_idle_ext_first(true,'18621575908','110@nway.com',0,1);

CloudCC使用说明(一)架构

截止2023年3月使用FSGUI完成的语音或视频的智能化的文档列表

开源双路语音流输出的mod_rst

宁卫云呼叫平台使用手册