1、JTAPI 简述
JTAPI 是之前 SUN (现在已经属于Oracle) 于1996年,联合Intel、Lucent、Novell等多间公司(噢:当年何等风光,到现在,除了Intel之外,倒的倒,卖的卖。。),制定的用于 Telphone 技术的,Java 开发框架协议。是一套用来控制电话(语音通讯)拨打操作过程的 API 协议集,通过这套API,我们可以使用程序来模拟和控制电话的拨打、接听、挂机、转接(呼叫路由)、语音播放、电话会议、接收按键等等。可以实现,不需要人员干预情况下,自动完成所有电话操作。
JTAPI 是一套 API 接口标准,而具体的实现由语音系统生产商进行。不同的公司有自己的不同实现,例如 Cisco 有自己的实现,AVAYA有自己的实现等等。本文除了说明 JTAPI 标准本身之外,还会涉及到 Cisco 的实现。从个人开发经验来说,标准能够做到的东西比较基础和简单,真正要做到完全控制或深入控制,还是依赖于厂家专有的实现。
JTAPI目前的最新版本是1.4,不过似乎1.2这个版本用得最多。以Cisco为例,到目前最新版本的CCM 10.5,对JTAPI的支持依然停留在1.2。下面是JATPI框架的标准结构图:
这是 JTAPI 应用分布示意图,虽然服务器端与应用端可以运行在同一台机,不过绝大多数生产系统会分开来,所以这里只给出分布式示意图,服务器端与应用端通常会使用“心跳”来通讯。
JTAPI标准由核心层和扩展层组成,下面是其结构图:
内层 JTAPI Core 提供最基本的呼叫控制(如拨打、接听和各类事件等),而外层则是提供更丰富和高级的控制。例如“Call Center Extension”提供呼叫中心服务,“Call Control Extension”提供非常详细的呼叫过程控制。
在这里特别说一下“Call Control Extension”,从开发的角度来说,JTAPI Core API 的可用性不高,因为都是非常基本的拨打、挂断,得到的拨打事件也是简单和不多。真正可用的是“Call Control Extension”,这里提供了转接、会议等呼叫控制。同时,在这个基础上各厂家提供了完整的,针对自己语音系统的 API 控制。所以,在实际开发过程中,常常会用 Call Control Extension 的 API。
JTAPI 标准的理念,就是将呼叫过程对象化,可以说是面向对象开发的一个比较好的范例。下面是呼叫过程的一个抽象示意图(JTAPI 呼叫模型):
要注意,上图所示的呼叫模型,都是逻辑概念。并不是指特定的物理概念。例如“Terminals”,可以是一台物理话机,一个生存在服务器内部的虚拟话机,甚至是一个没有按键和麦克风的喇叭等等。并且,最重要的一点,要明白所有这些对象的状态,是动态状态,也就是说,在拨打过程中对象状态会随着过程的推进,在不断变化。这是 JTAPI 开发与其他开发最大的不同之外。
每发起一个呼叫,都会创建上述的一个或多个对象。下面用一张简单的图来说明这些对象的直接关系(即有方法可以直接获取):
例如,我们可以使用 Call 来得到 Connection 对象,但是无法直接获取 Terminal 对象。但是,这并不重要。因为我们可以通过即时的事件来得到。又或者通过本地对象来得到,例如 Cisco CCM 实现的 CiscoCall ,我们就可以得到呼叫方和被呼叫方的 Terminal。
噢,似乎 JTAPI 并不复杂。。。实际上,这只是个开始而已,正如紫霞猜不出结局那样。JTAPI 的麻烦与复杂之处在于,其开发过程是事件驱动的。所有的事件,几乎都是并发事件。不同的事件对应特定的情景,情景中的各种对象都有着自己特定的状态。下面简单介绍一下 JTAPI 在开发内容与注意事项。
2、JTAPI 开发(以Cisco JTAPI 为例)
2.1 拨号呼叫流程
正如上面所说,JTAPI 的开发是事件驱动型开发。我们要介入呼叫过程,必须要接入和侦听呼叫过程所产生的事件。所以,要学习 JTAPI 的开发,首先就要看呼叫流程,下面以 Core Control Extention 为例(JTAPI Core 过于简单):
2.2 开发基本流程思路
要开发一个 JTAPI 应用,可以遵循下面的方法进行学习与开发:
2.3 开发过程中的常用类
下面例出开发过程中常用的类及其在 Cisco 中的实现要点:
○ 这是 JTAPI 总接入点。无论是发起一个 Call (呼叫),还是获取 Terminals。
○ 每个 Provider,对应 Cisco CCM 上一个 Application User 。也就是说,Application User 的权限就是 Provider 对 Phone (话机)的操作权限。
○ Provider 通过 Application User 来拥有自己所控制的 Phone 和 Addreses。
○ 通过 Provider,例如可以:
createCall() : 创建一个 Call,可以用来拨号连接
getCalls() : 获取 Provider 所有 Call
getTerminals() : 获取 Provider 所有能够控制的 Phone
getAddresses() : 获取 Provider 下所有 Address
addObserver( ProviderObserver) : 添加一个事件侦听器
shutdown() : 关闭和结束 Provider
○ Cisco 的实现类: CiscoProvider ,我们可以将 Provider 强制转换为 CiscoProvier 得到更强功能
getMediaTerminals() : 获取 Cisco CCM 所特有的逻辑话机
deleteCall( ) : 删除一个不再使用的 Call 。。。等等
○ Provider 事件侦听接口,主要的 Provider 事件包括:
ProvInServiceEv : Provider.IN_SERVICE 状态事件,表示 Provider 准备就绪,可以使用。
ProvOutOfServiceEv: Provider 处于离线状态,此时我们无法使用 Provider 进行工作
ProvShutdownEv: Provider 结束关闭事件
○ Cisco 实现: CiscoProviderObserver -- 将提供更多的事件,例如:
CiscoTermCreatedEv: 当我们为 Provider 添加一个新 Phone 时,就会触发此事件。应用可以不用重启,就可以使用本事件感知有新的话机加入,并为其提供应用或服务。
CiscoTermRemovedEv: 从 Provider 的 Phone 控制列表中移走 Phone时,会触发此事件。应用可以知道什么 Phone 不再受控,而不会操作到不存在的 Phone ,产生异常信息。
CiscoAddrCreatedEv/CiscoAddrRemovedEv : 同上
等等。。更加细致的通知事件
○ 呼叫对象,包含 0 或多个 Connection 对象。(例如 电话会议时,会有多个 Connection)
○ 主要方法包括:
addObserver() : 添加 Call 事件侦听器。
connect() : 发起一个呼叫(拨号)。要注意,必须拨号者、被拨号者和 Provider 处理可用状态,才能成功。
getConnections(): 获取 Call 的所有 Connection 对象。
getProvider() : 获取 Provider 对象
○ Call Control Extension 的增强对象: CallControlCall --- JTAPI Core Call 对象相对简单一些,增强之后,可以获得的主要方法:
conference() : 电话会议
consult(): 电话咨询。。比 conference() 更泛的单方或多方通话等操作。
drop() : 挂断。
transfer() :呼叫转移
。。。更多
○ Cisco 实现类: CiscoCall -- 这个类继续自 CallControlCall ,所以具有其一切功能,并还能获得:
1)拨号方与被拨号方的 Terminals
2)如果进行了 transfer 或 redirect 操作,可以通过本类获得相关信息
3)获得 CiscoConferenceChain,从而进一步获取电话会议的所有 Call 等信息 。(例如,踢人那个爽。。)
(待续)