在本文中,我们将了解Voicexml的一些功能与局限性,以及在应用程序中整合Voicexml与CCxml的细节。
在上一篇有关SCSML的文章中,我们讨论了状态机器表示法,并提到:许多概念都源自呼叫控制xml(CCxml)语言。CCxml规范的初稿出现于2002年初,现在还处于工作草稿阶段。但是,缺乏最终的推荐并非电信行业的障碍,并已存在几种CCxml产品,如惠普的OpenCall媒体平台(OpenCall Media Platform)或开源的Asterisk平台。
呼叫控制xml旨在为Voicexml之类的对话系统提供电话呼叫控制支持。它还可用作第三方电话系统中的呼叫控制管理器。XXSML 1.0规范定义了状态机器与事件处理语法,以及一整套标准的呼叫控制元素。
在本文中,我们将了解Voicexml的一些功能与局限性,以及在应用程序中整合Voicexml与CCxml的细节。电话应用程序需要实时接收并处理大量的事件。这些事件来自程序外部——基础电话平台或其它的事件源。CCxml程序包括某些事件到达时执行的事件处理器。CCxml还提供一个建立多方呼叫的强大而灵活的方法。
注:本文的下载版本包括所有可在文本文件中方便使用的代码实例。
主要的概念与术语
CCxml可作为任何电话系统中的呼叫控制管理器。起初有为支持新功能而给Voicexml添加新标签的意图。但是,规范的设计者不断在Viocexml的设计目标与CCxml要求间遭遇冲突。CCxml与Viocexml执行之间并非相互信赖。CCxml可能或不可能支持语音对话,或可能支持除Viocexml以外的对话语言。
CCxml完成下列需求:
CCxml应用本身就是一个CCxml文件集,它们共同建立一个完整的应用/程序。CCxml应用的一个单独实例称为CCxml任务(Session)。一个任务可以跨越多个文件和电话呼叫。为方便与语音对话(Voice Dialog)进行交互,CCxml连接被称为“呼叫线路”或系统资源。
连接之间,或连接与会议对象之间的媒体流需要由CCxml解释器进行追踪并作为真实的系统资源。活跃的语音对话与特定的连接联合,并通过它与来自其它连接或会议对象的单向或双向媒体流交互。会议对象模仿混合媒体流的资源。
CCxml程序通过CCxml语言中定义的元素来操作这些实体。它们还可以发送和/或接收与这些实体相关的异步事件。CCxml程序与语言中的各种元素一同操作连接对象与会议对象,这点将在下面讨论。在线路信号、线路状态报告信息、或发生错误与故障时,CCxml也可以从连接与会议对象那里接收事件。CCxml程序也能够使用语言元素开启或终止语音对话。通过事件机制也能产生其它交互。CCxml任务还能在彼此之间发送与接收事件。
CCxml中的事件是一个应用能够响应的行为或事件。打入的电话、对话行为或用户定义的事件都是事件实例。CCxml中的事件以ECMAScript对象为模型,并可以包含复杂的值。
实例中的呼叫控制结构
现在我们来看一些实例并设法了解这些实例的目的。第一个实例(Exmaple1.txt)是一个简单的“世界你好” CCxml应用程序,它由一个打入的电话启动,然后应用程序简单给一个变量赋值,在平台日志中写入信息后退出。
实例1
<?xml version="1.0" encoding="us-ascii"?>
<scxml version="1.0" xmlns="http://www.w3.org/2005/07/scxml"
initialstate="S1">
<state id="S1">
<transition event="Event1" target="S2"/>
</state>
<state id="S2">
<transition event="Event2" cond="X>0" target="S1"/>
<transition event="Event2" cond ="X<0" target next="S3"/>
</state>
<state id="S3">
</state>
</scxml>
<ccxml>是一个CCxml文档的母元素,它将整个CCxml脚本围在一个文档中。<ccxml>被执行时,它的子元素按逻辑方式集中在文档的开头,并在目标<eventprocessor>之前按文档顺序执行。这一过程称作文档初始化。<eventprocessor>充当<transition>元素的容器。一个有效的CCxml文档只能有唯一一个<eventprocessor>元素,且只能包含<transition>元素。
当被选中时,<transition>的内容指定将要执行的行为。它的“事件”属性是一个指示匹配事件类型的模型。事件类型是任意长度的以点分隔的字符串。变量用<var>元素来宣称,并通过评估可选属性”expr”的结果,以ECMAScript表达式的格式进行初始化。之后,变量的值可能会随着<assign>元素一同改变。<log>允许应用程序生成一个日志或调试信息,它可以帮助开发人员进行应用程序开发,或对应用程序的性能进行执行后分析。信息显示或记载的方式由平台决定。<exit>终止执行CCxml任务。所有未决的事件全被抛弃,且没有办法重新启动CCxml。
事件处理
事件处理是CCxml最强大的功能之一。CCxml事件可在任何时候,由许多资源提交。这种灵活的事件处理机制是许多电话应用程序的基础。
每个CCxml解释器都有一个队列,进入的事件排列在其中,并按到达时间进行分类。CCxml程序员只能通过<eventprocessor>事件及相关的<transition>事件来访问队列中的事件。CCxml任务事件队列一般以先进先出(FIFO)的形式运作,即将要处理的事件从队列前面移除,新事件则添加在队列的末尾。这一行为有两种例外:一是指定时间延迟的事件;二是某些总是位于队列前部的特殊事件。
事件可以用<send>元素发送到CCxml任务中,在这种情况下,可能会指定一个可选的延迟。延迟指定后,事件被发送到目标CCxml任务,但直到延迟时间消逝,它才会放进事件队列中。当延迟时间耗尽后,事件才被放到队列的末尾。
<eventprocessor>由一个固有的事件处理器解释运算法则(EHIA)来解释。EHIA的主循环从CCxml任务的事件队列中去除第一个事件,然后从包含在<eventprocessor>的<transition>组中进行选择。一个<transition>总是指示一组认可的事件类型,并可能进一步指明将要评估的ECMAScript条件表达式。接受刚刚移除事件类型的那个<transition>有一个满足的条件表达式,按文档顺序第一个出现在<eventprocessor>中,为选中的<transition>。
如果一个事件没有被<eventprocessor>中的任何一个<transition>选中,则CCxml平台应该用“失败”标签来记录此事件。CCxml平台可为“失败”标签配置任何期望的部署。这应该(但并非必须)等同于Default-transition.txt中的转换过程。
默认转换(Default Transition)
<transition event="*" name="ev">
<log label="'missed'" expr="ev.toString()"/>
</transition>