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

  • 体验方式

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

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

<shapetype id="_x0000_t75" stroked="f" filled="f" path="m@4@5l@4@11@9@11@9@5xe" o:preferrelative="t" o:spt="75" coordsize="21600,21600"><stroke joinstyle="miter"></stroke><formulas><f eqn="if lineDrawn pixelLineWidth 0"></f><f eqn="sum @0 1 0"></f><f eqn="sum 0 0 @1"></f><f eqn="prod @2 1 2"></f><f eqn="prod @3 21600 pixelWidth"></f><f eqn="prod @3 21600 pixelHeight"></f><f eqn="sum @0 0 1"></f><f eqn="prod @6 1 2"></f><f eqn="prod @7 21600 pixelWidth"></f><f eqn="sum @8 21600 0"></f><f eqn="prod @7 21600 pixelHeight"></f><f eqn="sum @10 21600 0"></f></formulas><path o:connecttype="rect" gradientshapeok="t" o:extrusionok="f"></path><lock aspectratio="t" v:ext="edit"></lock></shapetype><shape id="_x0000_i1027" style="WIDTH: 306.75pt; HEIGHT: 67.5pt" type="#_x0000_t75"><imagedata o:title="" src="file:///C:%5CDOCUME~1%5CGAOLIN~1%5CLOCALS~1%5CTemp%5Cmsohtml1%5C09%5Cclip_image001.png"></imagedata></shape>

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

<shape id="_x0000_i1028" style="WIDTH: 307.5pt; HEIGHT: 67.5pt" type="#_x0000_t75"><imagedata o:title="" src="file:///C:%5CDOCUME~1%5CGAOLIN~1%5CLOCALS~1%5CTemp%5Cmsohtml1%5C09%5Cclip_image003.png"></imagedata></shape>

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

<shape id="_x0000_i1029" style="WIDTH: 242.25pt; HEIGHT: 315pt" type="#_x0000_t75"><imagedata o:title="" src="file:///C:%5CDOCUME~1%5CGAOLIN~1%5CLOCALS~1%5CTemp%5Cmsohtml1%5C09%5Cclip_image005.png"></imagedata></shape>

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

4点击绿色“呼叫”按钮

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

  • Web Callback系统设计思想

Ø 系统组件:

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

<shape id="_x0000_i1025" style="WIDTH: 353.25pt; HEIGHT: 373.5pt" filled="t" type="#_x0000_t75" o:ole=""><font size="3"><fill opacity="0" color2="black"></fill><imagedata o:title="" src="file:///C:%5CDOCUME~1%5CGAOLIN~1%5CLOCALS~1%5CTemp%5Cmsohtml1%5C09%5Cclip_image007.emz"></imagedata></font></shape>

Ø 系统网络图

<shapetype id="_x0000_t75" stroked="f" filled="f" path="m@4@5l@4@11@9@11@9@5xe" o:preferrelative="t" o:spt="75" coordsize="21600,21600"><stroke joinstyle="miter"></stroke><formulas><f eqn="if lineDrawn pixelLineWidth 0"></f><f eqn="sum @0 1 0"></f><f eqn="sum 0 0 @1"></f><f eqn="prod @2 1 2"></f><f eqn="prod @3 21600 pixelWidth"></f><f eqn="prod @3 21600 pixelHeight"></f><f eqn="sum @0 0 1"></f><f eqn="prod @6 1 2"></f><f eqn="prod @7 21600 pixelWidth"></f><f eqn="sum @8 21600 0"></f><f eqn="prod @7 21600 pixelHeight"></f><f eqn="sum @10 21600 0"></f></formulas><path o:connecttype="rect" gradientshapeok="t" o:extrusionok="f"></path><lock aspectratio="t" v:ext="edit"></lock></shapetype><shape id="_x0000_i1025" style="WIDTH: 414.75pt; HEIGHT: 375pt" type="#_x0000_t75"><imagedata o:title="未命名10" src="file:///C:%5CDOCUME~1%5CGAOLIN~1%5CLOCALS~1%5CTemp%5Cmsohtml1%5C17%5Cclip_image001.png"></imagedata></shape>

<shape id="_x0000_i1026" style="WIDTH: 7in; HEIGHT: 455.25pt" filled="t" type="#_x0000_t75" o:ole=""><font size="3"><fill opacity="0" color2="black"></fill><imagedata o:title="" src="file:///C:%5CDOCUME~1%5CGAOLIN~1%5CLOCALS~1%5CTemp%5Cmsohtml1%5C09%5Cclip_image009.emz"></imagedata></font></shape>

Ø 安装、部署思路

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库中检出

svncheckout 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-<chsdate w:st="on" year="1899" month="12" day="30" islunardate="False" isrocdate="False">1.4.11</chsdate>(对应asterisk的源代码目录)

endif

MODULES_DIR=$(ASTLIBDIR)/modules

2.执行三部曲

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

. 修改所有配置文件

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.利用这个表,我们将决定用户的主叫号码是否可以再次参加我们的活动。

你可能感兴趣的:(Web,mysql,PHP,SVN,F#)