构建VoIP Web callback系统 ---基于Web方式的phone2phone通信方式(2)

来源:互联网 发布:java正整数分解质因数 编辑:程序博客网 时间:2024/06/04 23:19
   
  • 体验方式

我们使用开源软交换机(open-source IPBX)Asterisk实现Web callback功能,用户体验方式为:

1. 在首页输入您的电话号码:

  

2.点击“立即拨打”按钮:

 

 

3在弹出页面输入您朋友的电话号码(固定电话加区号)

 

4点击绿色“呼叫”按钮

上面弹出来的对话框,是基本用户的体验方式考虑的,它还是一个网页,不是Skype客户端,由于这是一个免费的活动,所以没有考虑作为一个标准的基于Webcallback认证功能,另外,用户也不需要输入用户名与密码等信息。直接就可以在网页中输入主叫与被叫号码来体验。

  •  Web Callback系统设计思想

Ø         系统组件:

    

   

   

Ø         系统网络图

  

   

    

Ø         安装、部署思路

l         Web trigger

1.       配置文件config.php在这个文件里说明了callback.php中将要通过AMI连接Asterisk的连接端口(5038)用户名、密码等这个在Callback engine层的manager.conf配置文件中说明

2.       服务器处理文件callback.php,在这个外部文件中执行对应主叫与被叫的拨号方案,先后拨通主叫与被叫。

l         Callback engine

AMI层的配置(为了在外部程序中执行Asterisk,需要赋予权限,就在manager.conf中设置)

manager.conf中添加结点

;用户名

[admin]

;密码

secret = 123456

;不同级别的认证信息

read = system,call,log,verbose,command,agent,user

write = system,call,log,verbose,command,agent,user

 

拨号方案的配置

/etc/asterisk/目录上新建了一个专用于这个项目的IVR配置文件web_callback.conf

;对应主叫方的拨号方案

[skype-web-callback-dial]

;在主叫方的手机上来电显示被叫的手机号

exten => s,1,Set(CALLERID(all)=${CALLED})

;先拨通主叫,如果主叫没通,被叫的输出通道(不存在被叫Sip通道),即被叫的拨号方

;(a.b.c.d为落地网关的IP地址)

exten => s,2,Dial(SIP/${CALLING}@a.b.c.d||gjA(Welcome))

;如果主叫接听了,记录下主叫是在响铃后主动挂断

exten => s,3,Set(CDR(userfield)=Hangupcause:${HANGUPCAUSE})

exten => s,4,Hangup()

;如果是主叫在响铃一段时间后又不响了,记录下是否由于发生了500的服务器错误。

exten => h,1,Set(CDR(userfield)=Hangupcause:${HANGUPCAUSE})

 

;对应被叫的拨号方案

[skype-web-callback-answer]

;在被叫方的手机上来电显示主叫的手机号

exten  => s,1,Set(CALLERID(all)=${CALLING})

;对于被叫来说需要满足以下需求:

;1.与主叫的通话时间保持5分钟,所以L()这个Dial应用的option选项恰能满足,其中L()第一个参数300000(ms)是总的通话时间,5分钟,第二个参数20000表示还剩下20秒时主叫方将听到timeleft系统提示音(由三个语音文件组成: vm-youhave.gsm

[你还有],20.gsm [20],queue-seconds.gsm[秒通话时间])

有关L()几个参数的说明:

 'L(x[:y][:z])' -- Limit the call to 'x' ms warning when 'y' ms are left (repeated every 'z'ms)

--Only 'x' is required, 'y' and 'z' are optional.

--The following special variables are optional:

**LIMIT_PLAYAUDIO_CALLER (default yes) Play sounds to the caller.

**LIMIT_PLAYAUDIO_CALLEE Play sounds to the callee.

**LIMIT_TIMEOUT_FILE File to play when time is up.

**LIMIT_CONNECT_FILE File to play when call begins.

**LIMIT_WARNING_FILE File to play as warning if 'y' is defined.

--'timeleft' is a special sound macro to auto-say the time left and is the default.

 

;2.${ANSWEREDTIME} 为通道变量,利用被叫方的这个通道变量,可以获取到被叫总的通话时间,根据${ANSWEREDTIME}的值是否等于5分钟,如果通话时间还未到时,被叫方挂断电话,此时转到执行exten  => s,7,Playback(PartnerHangup)主叫听到 PartnerHangup[对方已挂机...],如果通话时间已到,转到执行exten=> s,5,Playback(TimeoutHangup)[通话时间到...]

   ;3.利用另外一个通道变量${HANGUPCAUSE},它将记载从落地网关返回的与PSTN级错误有关的信息,查找 Asterisk wiki上的Recommended SIP <-> ISDN Cause codes部分:

http://www.voip-info.org/wiki/index.php?page=Asterisk+variable+hangupcause

如被叫无人接听返回的是1819no answer from the user,转换成Sip返回码为:           

 480 Temporarily unavailable,如果Dial未成功(被叫响铃一会就断了,或者根本没响铃等异常情况),此时记载下错误码,然后转到相应的执行方案,如无人接听[s-19]

exten  =>s,2,

Dial(SIP/${CALLED}@ a.b.c.d ||gjL(300000:20000:20000:0:1:timeleft::timeleft))

exten  => s,3,Set(CDR(userfield)=Hangupcause:${HANGUPCAUSE})

exten  => s,4,GotoIf($[${ANSWEREDTIME} = 300]]?5:7)

exten  => s,5,Playback(TimeoutHangup)

exten  => s,6,Hangup()

exten  => s,7,Playback(PartnerHangup)

exten  => s,8,Hangup()

exten  => s,103,Goto(s-${HANGUPCAUSE},s,1)

exten  => h,1,Goto(s-${HANGUPCAUSE},s,1)

 

;系统忙

;503 Service unavailable

[s-38]

exten => s,1,Playback(SystemBusy)

exten => s,2,Hangup()

;用户忙,拒绝接听此次来电

;call rejected

;403 Forbidden

[s-21]

exten => s,1,Playback(PartnerBusy)

exten => s,2,Hangup()

;电话无人接听

;no user responding

[s-18]

exten => s,1,Playback(PartnerAway)

exten => s,2,Hangup()

;电话无人接听

;no answer from the user

;480 Temporarily unavailable

[s-19]

exten => s,1,Playback(PartnerAway)

exten => s,2,Hangup()

 

l         系统日志层

CDR记录的保存

Asterisk可以存储CDR记录到一个MYSQL数据库中,也可以选择以CSV文本文件的形式保存起来,在Tom-Skype callback系统中,我们选择了保存到MYSQL数据库。由于Mysql客户端开发库的版权问题,Mysql billing应用程序不再作为Asterisk标准发布版本中的其中一部分来发布,而是以附加内容的形式存在:asterisk-addons,为了让Asterisk支持把CDR日志保存到mysql数据库中,必须下载asterisk-addons包,然后编译与mysql有关的几个模块,并且装载到Asterisk服务器中。

.下载asterisk-addons包。

有两种方式:

1:官方网站上发布的:

http://downloads.digium.com/pub/asterisk/,如果你当前使用的asterisk.14版本而且是最新的,这时候从目录中找到最新的asterisk-addons包。

    2:从SVN库中检出

     svn checkout  http://svn.digium.com/svn/asterisk-addons/branches/1.4/,用这种方法要注意几点:

http://svn.digium.com/svn/asterisk-addons/,这个根目录下面,有

branches/

tags/

team/

trunk/

这几个目录,如果你当前使用的asterisk.14版本而且是最新的,这时候应该要从branches分支目录中找到最新的版本下载,注意:不要直接check out trunk/目录。

. 编译安装asterisk addons

1. 修改Makefile文件

在编译asterisk addons之前,必须修改asterisk addons源文件下的Makefile

CFLAGS+=-fPIC 

       ifeq ($(OSARCH),SunOS)           

       ASTETCDIR=/var/etc/asterisk

       ASTLIBDIR=/opt/asterisk/lib

else

ASTLIBDIR=/usr/lib/asterisks (对应asterisk安装后的模块目录上一级目录)

       ASTETCDIR=/home/asterisk-1.4.11(对应asterisk的源代码目录)

endif

MODULES_DIR=$(ASTLIBDIR)/modules

 

2.执行三部曲

确定已经有了zlib-develmysql-devel(/usr/lib/mysql/)
# make clean
# make
# make install

 

. 修改所有配置文件

    1:编辑cdr_manager.confenabled = yes

   2:编辑modules.conf,在[modules]

增加:load => cdr_addon_mysql.so

3:编辑cdr_mysql.conf,如果目前还没有这个文件,新创建一个

[global]

hostname=localhost (Mysql数据库服务器)

dbname=skypecallback  (数据库名)

user=root 

password=123456

port=3306

sock = /var/run/mysqld/mysqld.sock

userfield=1

.Mysql数据库中新建数据数据库、表

      CREATE DATABASE skypecallback;

         CREATE TABLE `cdr` (
`calldate` datetime NOT NULL default '0000-00-00 00:00:00',
`clid` varchar(80) NOT NULL default '',
`src` varchar(80) NOT NULL default '',
`dst` varchar(80) NOT NULL default '',
`dcontext` varchar(80) NOT NULL default '',
`channel` varchar(80) NOT NULL default '',
`dstchannel` varchar(80) NOT NULL default '',
`lastapp` varchar(80) NOT NULL default '',
`lastdata` varchar(80) NOT NULL default '',
`duration` int(11) NOT NULL default '0',
`billsec` int(11) NOT NULL default '0',
`disposition` varchar(45) NOT NULL default '',
`amaflags` int(11) NOT NULL default '0',
`accountcode` varchar(20) NOT NULL default '',
`uniqueid` varchar(32) NOT NULL default '',
`userfield` varchar(255) NOT NULL default ''
);
ALTER TABLE `cdr` ADD INDEX ( `calldate` );
ALTER TABLE `cdr` ADD INDEX ( `dst` );
ALTER TABLE `cdr` ADD INDEX ( `accountcode` );

系统运行的即时监控

C++后台即时监控程序,根据CDR信息,它对数据库中的CDR记录表进行了二次统计,抽取出了有用信息,存到了另外一个表skypecallback.利用这个表,我们将决定用户的主叫号码是否可以再次参加我们的活动。