asterisk_phpagi简单开发第五版
- 格式:docx
- 大小:22.05 KB
- 文档页数:4
thinkphp 5手册
ThinkPHP 5 是一个基于 PHP 的开源的高性能 Web 应用开发框架。
它提供了强大的功能和灵活的扩展机制,使得开发人员能够快
速构建各种规模的 Web 应用程序。
ThinkPHP 5 的官方手册提供了
详细的文档和示例,帮助开发人员更好地理解和使用框架。
在 ThinkPHP 5 的手册中,你可以找到关于框架的安装、配置、路由、控制器、模型、视图、数据库操作、模板引擎、表单验证、
文件操作、缓存、日志、错误处理、插件开发、扩展开发等方面的
详细说明。
手册中还包括了框架的核心概念、设计理念以及最佳实
践等内容,帮助开发人员更好地理解框架的设计思想和使用方法。
此外,手册中还提供了大量的示例代码和实用的技巧,帮助开
发人员快速上手并提高开发效率。
开发人员可以通过手册快速查找
到他们需要的信息,并且可以根据手册中的指导进行实际操作和调试,从而更好地掌握框架的使用方法。
总之,ThinkPHP 5 的官方手册是开发人员学习和使用该框架的
重要参考资料,通过仔细阅读和实践,开发人员可以更好地掌握框
架的各项功能和特性,进而更高效地开发 Web 应用程序。
希望这些信息能对你有所帮助。
基于Asterisk的VoIP开发指南——(1)实现基本呼叫功能2008/06/12说明:1.本文档探讨基于Asterisk如何实现VoIP的一些基本功能,包括基本呼叫功能的方案选取、主叫号码透传、如何编写Asterisk AGI程序、Radius认证计费模块等。
2.本文档VoIP软终端使用X-Lite,其它终端均可以接入测试。
3.文章内容仅供参考,转载请注明出处。
1 VoIP系统相关协议和标准由于I P电话技术标准的开发涉及多个领域,因此,VOIP系统要想实现这些IP 电话之间的通信,则必须提供支持这些协议的实现。
目前主要涉及的协议如图1-1所示,其中除了HTTP是与WWW相关的协议外,其它的都是VOIP相关协议。
图1-1 所有基于IP协议的协议族由图1 -1可以看出,与VOIP相关的协议共分五层,每一层又由许多协议组成。
目前有关IP电话制定的标准体现在应用层。
而应用层又可分为信令控制协议、网关控制协议、媒体编码和传输协议和QOS协议等。
1.信令控制协议,目前被广泛接受的IP电话控制信令体系主要有ITU-T的H.323系列和IETF的会话初始化协议(SIP)。
2.网关控制协议,网关控制协议主要有媒体网关控制协议(MGCP)。
该协议是为了解决目前IP电话负担过重,不能满足未来容量和业务扩展的要求而设计的。
3.媒体编码,媒体编码主要有两类——视频编码和音频编码。
视频编码主要有H.261和H.263。
音频编码主要有G. 7xx系列。
4.实时传输协,实时传输协议有包括了实时传输协议(RTP)、实时传输控制协议(RTCP)、实时流协议(RTSP)和资源预留协议(RSVP)。
相关的协议标准可以参考相应的网上资料,在这不细述。
2 Asterisk简介Asterisk是一个开源的软件包,它可以运行PBX的所有功能,通常运行在Linux 操作系统平台上。
它不仅包含了PBX的功能,同时还有其它一些附加特性。
Asterisk 可以用三种协议来实现VoIP,同时可以与目前电话使用的标准硬件进行交互通信。
asterisk_phpagi简单开发第四版Asterisk phpagi开发入门不知不觉过了一个多月了哈,由于呼叫中心的项目进度比较缓慢,俺也就不急了,所以边做边玩,这一版俺讲讲AGI处理等待中的来电,当然这一个多月俺也把那个test.php 文件也做了一个比较大的改动。
具体请看下文。
本人水平有限,难免会有写的不周到或错误的地方,欢迎指正。
首先拨号规则基本没有动,前面几版都有说明,我就不再重复了先看看这个test.php脚本吧 #!/usr/bin/php�Cq//说明上面这个是php脚步的写法,/usr/bin/php是你的php安装目录(这段话是我写的说明,请勿放在test.php里)set_time_limit(60);ob_implicit_flush(false);include(\引用phpagi接口$num = $argv[1]; //这个就是带过来的通道变量${EXTEN}的值,获取来电者按了哪一个键或者拨了哪个分机$flag = $argv[2];//表示是分组还是直接拨分机号 $caller = $argv[3]; //来电号码$number = $num;//默认认为来电者直接拨分机号 $group = 0;//默认分组是0,表示直接拨分机号的 //表示是按了一个键,表示分组 if($flag){$group = $num; //分组号 $number =0;}$url=\.\r;$string = file_get_contents($url);//这个字符串是MV中间件返回的 $res = explode('|',$string);/*说明,我改动了这一部分$res[0]:规则状位(0:挂机或返回上一级、1:等待、2:可以接通)$res[1]:振铃状态(0:普通方式、1:同时振铃)$res[2]:可以dial的分机(如果$res[0]为2并且$res[1]为0,这里就是一个分机号;如果$res[0]为2并且$res[1]为1,这里就是多个分机号(SIP/8260&SIP/8263....),表示同时振铃 ) *//*调用远程接口去访问数据库,然后在接口里进行了复杂(嘻嘻)的运算,因为要考虑每个分机可能设置了呼叫转移啊,并且必须要满足一定的条件才可以触发呼叫转移,还有轮询查询每一个分机是否开启了呼叫保持,反正就是好几个递归,源码比较复杂,搞的我快精神崩溃了,呵呵,最终还是写出来了。
Asterisk phpagi开发入门第六版已经是一个初步完整的版本了,这一版,基本上算是第一阶段的收官之版了。
对于之前的录音问题,本人再次表示歉意。
本人水平有限,难免会有写的不周到或错误的地方, 欢迎指正。
首先拨号规则[ext-state]exten=> _XXXX,hint,SIP/${EXTEN}------------------------------------------------------没有变化重申一下 asterisk1.8的话,需要在 sip.conf 文件里需要改一个地方找到 ;callcounter=yes把前面的注释去掉好像有两处,随便某一处好像都可以context 我也做了一些优化和更新,请童鞋们注意[from-ivr-agi-transfer]exten => _XXXX,1,Dial(SIP/${EXTEN}exten => _XXXX,n,NoOp( Dial Status: ${DIALSTATUS}exten => _XXXX,n,Goto(s-${DIALSTATUS},1exten => s-NOANSWER,1,Goto(from-ivr-wait-hangup,w,1exten => s-CONGESTION,1,Goto(from-ivr-wait-hangup,w,1exten => s-CANCEL,1,Goto(from-ivr-wait-hangup,w,1exten => s-BUSY,1,Goto(from-ivr-wait-hangup,w,1exten => s-CHANUNAVAIL,1,Goto(from-ivr-wait-hangup,w,1-----------------------------------------------有变化了,这里主要解决了一个问题就是说在处理等待的 AGI 守护进程中再重定向之前,我会去判断一下被转移的目的分机是否状态正常正常则转移,不正常就继续等待,之前的 context 虽然实现了正常重定向转移但是对于 asterisk 的分机状态的获取很不稳定,也许判断的时候是正常的但是执行 AMI 指令开始重定向的时候分机是不正常的,导致来电会被挂掉这段新的 context 就是处理那种情况,让其继续等待,直到被转移成功或者时间到了挂掉,或者来电自己挂断[from-ivr-wait-hangup]exten => w,1,Playback(waitexten =>w,n,Playback(wait_mexten =>w,n,Hangup(exten => r,1,Playback(hungupexten =>r,n,Hangup([from-ivr-agi]exten => _66687XXX,1,Answer(exten => _66687XXX,n,Set(CHANNEL(language=cnexten => _66687XXX,n,Goto(from-ivr-agi,s,1exten => s,1,Background(companyexten =>s,n,Background(wait_mexten =>s,n,Hangup(exten =>_Z,1,AGI(script_mv_agi.php,${EXTEN},${CALLERID(num},${CHANNEL},0 exten => _Z,n,Hangup(include => from-ivr-wait-hangup-------------------------------------------------------注意exten =>_Z,1,AGI(script_mv_agi.php,${EXTEN},${CALLERID(num},${CHANNEL},0 最后一个参数表示多级分组的 ID 的字符串[two-from-ivr-agi]exten => s,1,Background(${IVR}exten =>s,n,Background(upexten =>s,n,Background(wait_mexten =>s,n,Hangup(exten =>_Z,1,AGI(script_mv_agi.php,${EXTEN},${CALLERID(num},${CHANNEL},${TEAM PATH} exten => _Z,n,Hangup(exten => *,1,Goto(from-ivr-agi,s,1exten => *,n,Hangup(include => from-ivr-wait-hangup----------------------------------------------------------exten =>_Z,1,AGI(script_mv_agi.php,${EXTEN},${CALLERID(num},${CHANNEL},${TEAM PATH} 最后一个参数表示多级分组的 ID 的字符串,这个是在 AGI 脚本里传过来的,下面我会说明 *号键返回上一级[three-from-ivr-agi]exten => s,1,Background(${IVR}exten =>s,n,Background(upexten =>s,n,Background(wait_mexten =>s,n,Hangup(exten =>_Z,1,AGI(script_mv_agi.php,${EXTEN},${CALLERID(num},${CHANNEL},${TEAM PATH} exten => _Z,n,Hangup(exten =>*,1,AGI(script_mv_agi.php,${EXTEN},${CALLERID(num},${CHANNEL},${TEAMP ATH} exten => *,n,Hangup(include => from-ivr-wait-hangup-------------------------------------------------------------------------这个是第三级目前是最后一级,当然是直接呼叫了*号键返回上一级 , 已经实现, AGI 脚本里会说明这个地方理论上可以支持无限分组了关键的exten =>_Z,1,AGI(script_mv_agi.php,${EXTEN},${CALLERID(num},${CHANNEL},${TEAM PATH} 和exten =>*,1,AGI(script_mv_agi.php,${EXTEN},${CALLERID(num},${CHANNEL},${TEAMP ATH} 这两段是不需要变的,这个也是核心,所以我说理论上原来的 test.php 我已经改名了 :script_mv_agi.php内容又变了#!/usr/bin/php -qanswer(;if($string{$res = explode('|',$string;$context = $res[4]; //当前所在的 contextif($res[0]==3{$agi->set_variable('IVR',$res[3];//这个就是对应分组播放的 IVR$team_path = $res[5];$agi->set_variable('TEAMPATH',$team_path;//这个就是当前分组的各级父分组的 ID 字符串$agi->exec_goto("$context,s,1";//注意 asterisk 1.8 这个地方是逗号。
asterisk_phpagi简单开发第五版Asterisk phpagi开发入门这一版改动相当大,可以说是一个全新的,因为从这一版开始,我的这个AGI需要实现一个asterisk支持多个企业(多个总机)的功能,具体点的话,就是通过判断被呼叫的总机获取该总机对应的企业信息(包括企业的IVR、企业设置的分组、设置的拨号规则、每个分组下面的分机)。
具体请看下文。
本人水平有限,难免会有写的不周到或错误的地方,欢迎指正。
首先我还是接第四版把来电超时转移简单说一下吧,其实很简单,就是再用一个MV中间件端的AGI守护进程来扫描数据库,来电等待是这样做的,来电超时转移也可以这样做呀,每隔几秒去扫一下数据库,哪些分机正在振铃(这个表就是第一版中我说的实现来电弹屏的基础表,同时也是判断分机状态的表,第二版有说明),然后挨个检查这些响铃的分机是否开启了呼叫转移,并且是否是超时转移,如果是判断一下响铃开始的时间到现在是否已经超过了设置的时间,超过了就转移。
当然,有些童鞋肯定会骂俺了,这样搞,效率不是吓死人的低啊。
对于这个问题,俺只能表示,俺是菜鸟,除了这种方法想不到其他的更好的办法了当然希望和童鞋们一起讨论,是不是说只能在这样的基础上去优化了,还是可以有一个全新的方案。
灰常的期待。
首先拨号规则,改动的相当大了支持多个企业[from-mytest-transfer]include => from-internal-additional-----------------------------------------------------------------------------------------------------上面这个呢就是第四版中说的呼叫转移(重定向)需要依赖的context[from-mytest]exten =>_.,1,Answer()exten => _.,n,AGI(script_mv_wivr.php,${CALLERID(num)},${EXTEN}) exten => _Z,1,AGI(script_mv_agi.php,${EXTEN},1,${CALLERID(num)},${CHA NNEL})exten => _Z,n,Hangup()exten => w,1,Background(wait)exten => w,2,Background(wait_m)exten => w,3,Goto(from-mytest,w,2);exten => ivr,1,Background(${IVR})exten => ivr,2,Goto(from-mytest,ivr,1);exten => r,1,Background(hungup)exten => r,2,Background(hungup_m)exten => r,3,Goto(from-mytest,r,2);----------------------------------------------------------------------------------------------解释一下exten => _.,n,AGI(script_mv_wivr.php,${CALLERID(num)},${EXTEN}) 这个就是通过被呼叫的总机比如66687100然后进入agi里再去调用mv中间件的接口查出数据库里设置的对应企业的IVR欢迎语音script_mv_wivr.php源码#!/usr/bin/php -qset_time_limit(60);ob_implicit_flush(false);include("phpagi.php");$caller = $argv[1];$num = $argv[2];$url="http://XXXX/index.php/asteriskagi/get_caller_info?caller=".$c aller."&tonum=".$num; $string = file_get_contents($url);//这里就是去查数据库啦$agi=new AGI;$agi->exec_setlanguage('cn');if($string){$agi->set_variable('IVR',$string);//这里是把被叫企业的IVR语音文件存入通道变量,因为下面的exten需要用到这个IVR语音变量$agi->exec_goto('from-mytest|ivr|1');//goto到播放IVR欢迎语音}else{$agi->exec_goto('from-mytest|r|1');}>/*说明:当然不仅仅是去数据库里查出对应企业的IVR语音文件就完事了,你还要把这个来电以及被叫总机存入数据库里以作记录,否则script_mv_agi.php再去调用MV中间件接口的时候,你知道它刚开始是打了哪个企业的总机么,如果不知道的话,如何去调用对应企业的分组和分机呢,是吧,具体怎么处理,童鞋们可以想想,也不复杂的*/exten => ivr,1,Background(${IVR})这里就是播放IVR欢迎语音,注意通道变量${IVR},这个就是在脚本里面设置的其他的童鞋们基本都能看懂吧,俺就不说了原来的test.php我已经改名了:script_mv_agi.php内容基本没变好像#!/usr/bin/php–qset_time_limit(60);ob_implicit_flush(false);include("phpagi.php");//引用phpagi接口$num = $argv[1]; //这个就是带过来的通道变量${EXTEN}的值,获取来电者按了哪一个键或者拨了哪个分机$flag = $argv[2];//表示是分组还是直接拨分机号$caller = $argv[3]; //来电号码$number = $num;//默认认为来电者直接拨分机号$group = 0;//默认分组是0,表示直接拨分机号的//表示是按了一个键,表示分组if($flag){$group = $num; //分组号$number =0;}$url="http://XX/?m=asteriskagi&act=agi&group=".$group. "&caller=".$caller."&tonum=".$numbe r;$string = file_get_contents($url);//这个字符串是MV中间件返回的$res = explode('|',$string);/* 说明,我改动了这一部分$res[0]:规则状位(0:挂机或返回上一级、1:等待、2:可以接通)$res[1]:振铃状态(0:普通方式、1:同时振铃)$res[2]:可以dial的分机(如果$res[0]为2并且$res[1]为0,这里就是一个分机号;如果$res[0]为2并且$res[1]为1,这里就是多个分机号(SIP/8260&SIP/8263....),表示同时振铃 )*//*调用远程接口去访问数据库,然后在接口里进行了复杂(嘻嘻)的运算,因为要考虑每个分机可能设置了呼叫转移啊,并且必须要满足一定的条件才可以触发呼叫转移,还有轮询查询每一个分机是否开启了呼叫保持,反正就是好几个递归,源码比较复杂,搞的我快精神崩溃了,呵呵,最终还是写出来了。
关于php的书籍PHP是一种广泛使用的开源脚本语言,用于Web开发。
它可以嵌入HTML中,也可以与各种数据库配合使用。
如果您想深入了解PHP,这里有一些值得推荐的书籍。
1.《PHP和MySQL Web开发》这是一本非常受欢迎的PHP入门书籍。
它介绍了如何使用PHP和MySQL创建动态网站,并提供了许多实用的示例代码和项目。
此外,它还包括有关安全性、性能优化和面向对象编程等主题的深入讨论。
2.《高效PHP编程》这本书旨在帮助读者提高他们的PHP编程技能,以便更快地构建高质量的Web应用程序。
它涵盖了各种主题,包括调试、测试、性能优化、并发和缓存等。
此外,它还提供了许多实用技巧和最佳实践。
3.《深入理解PHP内核》如果您想成为一名真正的PHP专家,则需要深入了解其内部工作原理。
这本书提供了关于PHP内核结构、代码执行流程和内存管理等方面的详细信息。
虽然它可能对初学者来说有点困难,但对于有经验的开发人员来说,它是一本非常有价值的参考书。
4.《PHP 7编程实战》PHP 7是最新版本的PHP,它提供了许多新功能和改进。
这本书介绍了如何使用PHP 7构建现代Web应用程序,并涵盖了诸如类型声明、异常处理和匿名类等新特性。
此外,它还提供了有关性能优化和安全性的实用建议。
5.《Laravel框架入门》Laravel是一种流行的PHP框架,用于快速构建高质量的Web应用程序。
这本书介绍了如何使用Laravel进行开发,并涵盖了诸如路由、控制器、模型和视图等主题。
此外,它还提供了有关如何使用Laravel 进行测试和部署的详细指南。
总之,这些书籍涵盖了从入门到专业级别的各种主题,适合不同层次的读者。
无论您是初学者还是经验丰富的开发人员,都可以从中获得有价值的知识和技能。
准备工作在完成IIS上进行PHP5安装配置工作之前,首先需要下载PHP5.2和PHP5.3,PHP5.3以php-5.3.2-Win32- VC9-x86为准,具体下载地址请参考PHP环境搭建:Windows7 Apache+PHP+Mysql一文。
Windows7 IIS7安装在进行IIS7 PHP安装配置之前,首先需要安装IIS7,Windows7默认并没有安装IIS,安装过程如下:首先进入控制面板,点击程序和功能,再点击左侧打开和关闭Windows功能,勾选Internet Information Services可承载的Web核心,确定安装。
在完成安装后,在勾选Internet信息服务,选择安装必要的IIS功能,注意由于在配置PHP5.2和PHP5.3 时,IIS7中是以ISAPI和FastCgi方式配置PHP的,所以Cgi和ISAPI 扩展和ISAPI筛选器务必勾选(此处由于我首先以ISAPI方式配置PHP5.2,我没有勾选Cgi),如图:安装IIS7在完成Windows7 IIS7的安装后,即可在控制面板中的管理工具中看到Internet信息服务管理器选项。
如何在Windows7 IIS7上以ISAPI方式配置PHP5.2?IIS7 PHP5.2配置第一步:php.ini配置解压php-5.2.13-Win32-VC6-x86.zip,重命名为php52iis,将其复制到C盘根目录下,将php.ini- list文件名更改为php.ini,打开php.ini进行配置,php.ini的配置与PHP环境搭建:Windows7 Apache+PHP+Mysql基本一样,注意extension_dir的目录指向必须准确,即1 extension_dir = "C:/php52iis/ext"另外在PHP5.2版本中没有date.timezone选项,所以无需设置。
在完成PHP5.2中php.ini的配置工作后,将其复制至C:\WINDOWS目录下,同时将PHP52iis目录下的libmcrypt.dll,libmysql.dll,php5ts.dll三个文件到C:/windows/System32目录下。
适合初学者的php书籍
对于初学者来说,选择一本适合自己的PHP书籍非常重要。
以
下是一些适合初学者的PHP书籍推荐:
1. 《PHP和MySQL Web开发》(作者,Luke Welling, Laura Thomson)这本书是PHP和MySQL方面的经典教材,适合初学者入门。
它涵盖了PHP基础知识以及与MySQL数据库交互的内容,对于想要
学习构建动态网站的人来说是一个很好的选择。
2. 《PHP对象与模式》(作者,Matt Zandstra)这本书专注
于PHP面向对象编程和设计模式,对于那些想要深入了解PHP的面
向对象特性和最佳实践的初学者来说是非常有用的。
3. 《Head First PHP & MySQL》(作者,Lynn Beighley, Michael Morrison)这本书以图文并茂的形式介绍了PHP和MySQL
的基础知识,适合初学者轻松上手。
4. 《PHP 7高级编程》(作者,Branko Ajzele)这本书适合
那些想要更深入地了解PHP 7新特性和高级主题的初学者,包括性
能优化、安全性等方面的内容。
以上是一些适合初学者的PHP书籍推荐,选择一本适合自己水平和需求的书籍,结合实际练习,相信能够帮助初学者快速入门和提高。
希望对你有所帮助。
Asterisk phpagi开发入门不知不觉过了一个多月了哈,由于呼叫中心的项目进度比较缓慢,俺也就不急了,所以边做边玩,这一版俺讲讲 AGI 处理等待中的来电,当然这一个多月俺也把那个test.php 文件也做了一个比较大的改动。
具体请看下文。
本人水平有限,难免会有写的不周到或错误的地方,欢迎指正。
首先拨号规则基本没有动,前面几版都有说明,我就不再重复了先看看这个 test.php 脚本吧#!/usr/bin/php– q//说明上面这个是 php 脚步的写法, /usr/bin/php是你的 php 安装目录 (这段话是我写的说明,请勿放在 test.php 里answer(;//$agi->verbose($number;//表示可以接通(上面红色注解部分if($res[0]==2{$agi->exec_setlanguage('cn';$agi->stream_file('welcome','#';//表示是同时振铃(对于多个分机的情况if($res[1]==1{$agi->exec_dials($res[2];}//普通振铃(一个分机else{$agi->say_phonetic($res[2],'1234567890*#';$agi->stream_file('operator','#';$agi->exec_dial('SIP',$res[2];}}//表示进入等待else if($res[0]==1{$agi->exec_goto('from-mytest|w|1';//进入 IVR ,提示等待}//进入另一个 IVRelse{$agi->exec_goto('from-mytest|r|1';//进入 IVR ,提示挂机或者返回上一级}?>好,呼叫响铃咱们就不说了,我们说说进入等待吧我现在的实现还是比较简单的,在 MV 中间件的接口中我把需要进入等待的来电先扔进 memcached 中,让为防止 memcached 挂了,最好还是也先放入数据库中这里面还要考虑进入等待来电的一个排序,还有同时将来电的号码、被叫的分组、以及来电号码的通道,这些可以在 mv 中间件的接口处理好这样我们在 MV 中间件端又新加了一个 AGI ,我先简单介绍一下这个 AGI 的功能吧。
Asterisk模块编写2上一篇文章《Asterisk模块编写入门》里已经解释了Hello World Asterisk 模块。
该模块只实现了能够给Asterisk 编译,能够加载到Asteisk 中去,当被加载或卸载时打印简单的日志信息。
现在让该模块做些更有意义的事情。
作者/ Russell Bryant 翻译/ 高志在res_helloworld.c 中,我们应用了load_module 和unload_module 函数。
在那个模块中,我们仅仅是打印日志,其实在该模块中可以实现更多的功能。
load_module 的工作是说:“hello Asterisk, I’m a module. I can provide some features to Asterisk and here is how you use them."相反的,unload_module 的工作是“ Hello Asterisk, again. I’m about to disappear, so please don’t use any of these features that I was providing to you anymore. If you do, you’ll explode. kthx! ”现在是更新模块提供功能给Asterisk 的时候了。
我们将从CDR 处理开始,CDR 接口不算是一个非常简单的应用。
首先是添加合适的头文件。
#include "asterisk/cdr.h"然后,我们增加一个新的函数,该函数在每次CDR post 时将会调用,参数是CDR 本身。
复制代码1.static int cdr_helloworld(struct ast_cdr *cdr)2.{3.ast_log(LOG_NOTICE, "We got a CDR for channel '%s'. "4."Source: '%s', Dest: '%s', Duration: %ld\n",5.cdr->channel, cdr->src, cdr->dst, cdr->duration);6.7.return 0;8.}接下来,将刚刚实现的应用通过load_module() 和unload_module() 函数经新功能添加到该模块中去。
Asterisk使⽤AGI脚本执⾏控制台命令获取通道参数脚本如下require_once("/var/lib/asterisk/agi-bin/phpagi-asmanager.php");require_once("/var/lib/asterisk/agi-bin/phpagi.php");//使⽤Command必须先使⽤phpagi-asmanager的connect函数连接⾄后台$host = '127.0.0.1';$username = 'admin';$secret = '29666985';define('MAX_TRY_TIMES',3); //定义重试次数define('TIMEOUT',4000); //定义超时时间,单位毫秒$agi = new AGI(); //调⽤phpagi脚本中的函数$ami = new AGI_AsteriskManager();//调⽤phpagi-asmanager脚本中的函数$conn = $ami->connect($host,$username,$secret);if( $conn == false ){ //连接失败echo "Connection failed.\n";die;}$channel = $agi->get_variable("CDR(channel)"); //获取通道值$channel = $channel["data"];$arrReturn = $ami->Command("core show channel $channel");//在脚本中执⾏asterisk后台命令获取通道参数$lines=explode("\n", str_replace("\r\n", "\n", $arrReturn["data"]));$ary = array();$ary['Channel'] = substr($lines[2],strpos($lines[2],":")+2); //客户通道$ary['Extension'] = substr($lines[8],strpos($lines[8],":")+2); //分机号$ary['ExtenChannel'] = substr($lines[41],strpos($lines[41],"=")+1); //坐席通道$agi->set_variable("WKK",$ary['Extension']); //通道变量-分机号$agi->set_variable("ExtenChannel",$ary['ExtenChannel']); //坐席通道$ami->disconnect();。
Asterisk phpagi开发入门这一版改动相当大,可以说是一个全新的,因为从这一版开始,我的这个AGI需要实现一个asterisk支持多个企业(多个总机)的功能,具体点的话,就是通过判断被呼叫的总机获取该总机对应的企业信息(包括企业的IVR、企业设置的分组、设置的拨号规则、每个分组下面的分机)。
具体请看下文。
本人水平有限,难免会有写的不周到或错误的地方,欢迎指正。
首先我还是接第四版把来电超时转移简单说一下吧,其实很简单,就是再用一个MV中间件端的AGI守护进程来扫描数据库,来电等待是这样做的,来电超时转移也可以这样做呀,每隔几秒去扫一下数据库,哪些分机正在振铃(这个表就是第一版中我说的实现来电弹屏的基础表,同时也是判断分机状态的表,第二版有说明),然后挨个检查这些响铃的分机是否开启了呼叫转移,并且是否是超时转移,如果是判断一下响铃开始的时间到现在是否已经超过了设置的时间,超过了就转移。
当然,有些童鞋肯定会骂俺了,这样搞,效率不是吓死人的低啊。
对于这个问题,俺只能表示,俺是菜鸟,除了这种方法想不到其他的更好的办法了当然希望和童鞋们一起讨论,是不是说只能在这样的基础上去优化了,还是可以有一个全新的方案。
灰常的期待。
首先拨号规则,改动的相当大了支持多个企业[from-mytest-transfer]include => from-internal-additional-----------------------------------------------------------------------------------------------------上面这个呢就是第四版中说的呼叫转移(重定向)需要依赖的context[from-mytest]exten =>_.,1,Answer()exten => _.,n,AGI(script_mv_wivr.php,${CALLERID(num)},${EXTEN})exten => _Z,1,AGI(script_mv_agi.php,${EXTEN},1,${CALLERID(num)},${CHANNEL})exten => _Z,n,Hangup()exten => w,1,Background(wait)exten => w,2,Background(wait_m)exten => w,3,Goto(from-mytest,w,2);exten => ivr,1,Background(${IVR})exten => ivr,2,Goto(from-mytest,ivr,1);exten => r,1,Background(hungup)exten => r,2,Background(hungup_m)exten => r,3,Goto(from-mytest,r,2);----------------------------------------------------------------------------------------------解释一下exten => _.,n,AGI(script_mv_wivr.php,${CALLERID(num)},${EXTEN})这个就是通过被呼叫的总机比如66687100然后进入agi里再去调用mv中间件的接口查出数据库里设置的对应企业的IVR欢迎语音script_mv_wivr.php源码#!/usr/bin/php -q<?phpset_time_limit(60);ob_implicit_flush(false);include("phpagi.php");$caller = $argv[1];$num = $argv[2];$url ="http://XXXX/index.php/asteriskagi/get_caller_info?caller=".$caller."&tonum=".$num; $string = file_get_contents($url);//这里就是去查数据库啦$agi=new AGI;$agi->exec_setlanguage('cn');if($string){$agi->set_variable('IVR',$string);//这里是把被叫企业的IVR语音文件存入通道变量,因为下面的exten需要用到这个IVR语音变量$agi->exec_goto('from-mytest|ivr|1');//goto到播放IVR欢迎语音}else{$agi->exec_goto('from-mytest|r|1');}?>/*说明:当然不仅仅是去数据库里查出对应企业的IVR语音文件就完事了,你还要把这个来电以及被叫总机存入数据库里以作记录,否则script_mv_agi.php再去调用MV中间件接口的时候,你知道它刚开始是打了哪个企业的总机么,如果不知道的话,如何去调用对应企业的分组和分机呢,是吧,具体怎么处理,童鞋们可以想想,也不复杂的*/exten => ivr,1,Background(${IVR})这里就是播放IVR欢迎语音,注意通道变量${IVR},这个就是在脚本里面设置的其他的童鞋们基本都能看懂吧,俺就不说了原来的test.php我已经改名了:script_mv_agi.php内容基本没变好像#!/usr/bin/php–q<?phpset_time_limit(60);ob_implicit_flush(false);include("phpagi.php");//引用phpagi接口$num = $argv[1]; //这个就是带过来的通道变量${EXTEN}的值,获取来电者按了哪一个键或者拨了哪个分机$flag = $argv[2];//表示是分组还是直接拨分机号$caller = $argv[3]; //来电号码$number = $num;//默认认为来电者直接拨分机号$group = 0;//默认分组是0,表示直接拨分机号的//表示是按了一个键,表示分组if($flag){$group = $num; //分组号$number =0;}$url="http://XX/?m=asteriskagi&act=agi&group=".$group."&caller=".$caller."&tonum=".$numbe r;$string = file_get_contents($url);//这个字符串是MV中间件返回的$res = explode('|',$string);/* 说明,我改动了这一部分$res[0]:规则状位(0:挂机或返回上一级、1:等待、2:可以接通)$res[1]:振铃状态(0:普通方式、1:同时振铃)$res[2]:可以dial的分机(如果$res[0]为2并且$res[1]为0,这里就是一个分机号;如果$res[0]为2并且$res[1]为1,这里就是多个分机号(SIP/8260&SIP/8263....),表示同时振铃 )*//*调用远程接口去访问数据库,然后在接口里进行了复杂(嘻嘻)的运算,因为要考虑每个分机可能设置了呼叫转移啊,并且必须要满足一定的条件才可以触发呼叫转移,还有轮询查询每一个分机是否开启了呼叫保持,反正就是好几个递归,源码比较复杂,搞的我快精神崩溃了,呵呵,最终还是写出来了。
源码比较多,这边我就不放出来了,如果有需要的童鞋可以访问我的baidu空间,此用户被关机,给我留言 */$agi=new AGI;$agi->answer();//$agi->verbose($number);//表示可以接通(上面红色注解部分)if($res[0]==2){$agi->exec_setlanguage('cn');$agi->stream_file('welcome','#');//表示是同时振铃(对于多个分机的情况)if($res[1]==1){$agi->exec_dials($res[2]);}//普通振铃(一个分机)else{$agi->say_phonetic($res[2],'1234567890*#');$agi->stream_file('operator','#');$agi->exec_dial('SIP',$res[2]);}}//表示进入等待else if($res[0]==1){$agi->exec_goto('from-mytest|w|1');//进入IVR,提示等待}//进入另一个IVRelse{$agi->exec_goto('from-mytest|r|1');//进入IVR,提示挂机或者返回上一级}?>最后我说一下之前说过的录音吧之前的会生成两个独立的录音文件,而实际我们肯定是需要一个文件多方请教加上本人的尝试,竟然被俺搞出来了改动后的代码是这样$filename =$cller1."_".$cller2."_".date("Y-m-d-H-i-s",time());$request = "Action: Monitor\r\nChannel: ".$mainresponse['Channel1']."\r\nChannel2: ".$mainresponse['Channel2']."\r\nFile: ".$filename."\r\nMix: 1\r\n\r\n"; $tmcc->createAction($request,1);就是把被叫通道加上去,然后就OK了,上帝保佑,俺真的太幸运了。
====================================更正一下录音还是用下面这句代码$request = "Action: Monitor\r\nChannel: ". $mainresponse['Channel1']."\r\nFile: ".$filename."\r\nMix: TRUE\r\n\r\n";这里的话Mix 为1 表示生成一个录音文件但是需要你的系统安装sox很简单 yum sox 装上就OK了之前我无法生成一个文件的原因就是系统缺少sox所以很抱歉了。