JTAPI 开发入门 (一)

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 开发入门 (一)_第1张图片

  这是 JTAPI 应用分布示意图,虽然服务器端与应用端可以运行在同一台机,不过绝大多数生产系统会分开来,所以这里只给出分布式示意图,服务器端与应用端通常会使用“心跳”来通讯。

  JTAPI标准由核心层和扩展层组成,下面是其结构图:


                                    JTAPI 开发入门 (一)_第2张图片

  内层 JTAPI Core 提供最基本的呼叫控制(如拨打、接听和各类事件等),而外层则是提供更丰富和高级的控制。例如“Call Center Extension”提供呼叫中心服务,“Call Control Extension”提供非常详细的呼叫过程控制。

  在这里特别说一下“Call Control Extension”,从开发的角度来说,JTAPI Core API 的可用性不高,因为都是非常基本的拨打、挂断,得到的拨打事件也是简单和不多。真正可用的是“Call Control Extension”,这里提供了转接、会议等呼叫控制。同时,在这个基础上各厂家提供了完整的,针对自己语音系统的 API 控制。所以,在实际开发过程中,常常会用 Call Control Extension 的 API。

  JTAPI 标准的理念,就是将呼叫过程对象化,可以说是面向对象开发的一个比较好的范例。下面是呼叫过程的一个抽象示意图(JTAPI 呼叫模型):

                         JTAPI 开发入门 (一)_第3张图片

  要注意,上图所示的呼叫模型,都是逻辑概念。并不是指特定的物理概念。例如“Terminals”,可以是一台物理话机,一个生存在服务器内部的虚拟话机,甚至是一个没有按键和麦克风的喇叭等等。并且,最重要的一点,要明白所有这些对象的状态,是动态状态,也就是说,在拨打过程中对象状态会随着过程的推进,在不断变化。这是 JTAPI 开发与其他开发最大的不同之外。

  • Provider :语音服务提供者。可以看作是语音服务器,又或者形象地看作是电信局。
  • Call :一个拨打对象。每发起一个拨号,都会和需要创建一个 Call 对象。并且 Call 对象也不是一直存在,会因为一些呼叫方式的不同(例如转接,电话会议等)自动创建和销毁。
  • Connection:Call 与 Address 之间的逻辑连接。Call 与 Connection 是一对多的关系。我们可以使用这个对象来挂断呼叫,转接呼叫等
  • Address:逻辑号码。(理解为 QQ 号)
  • Terminal:终端。可以是一台物理终端,也可以是逻辑终端。例如 Cisco CCM 就提供了两个非常有用的逻辑终端:CTI Port 和 CTI RoutePoint。(噢:我们可以用 CTI RoutePoint 开发出一个语音聊天机器人。。。Cisco Call Center 就是使用 CTI RoutePoint 来实现语音流程)。一个 Terminal 可以有多个 Address;同样,一个 Address 也可以有多个Terminal (共享话机)。
  • Terminal Connection: Terminal Connection 是 Connection 与 Terminal 之间的逻辑连接。一个 Connection 可能有多个 Terminal Connection (例如共享话机的情形),使用 Terminal Connection 可以 answer 一个连接。

  每发起一个呼叫,都会创建上述的一个或多个对象。下面用一张简单的图来说明这些对象的直接关系(即有方法可以直接获取):

                            JTAPI 开发入门 (一)_第4张图片

  例如,我们可以使用 Call 来得到 Connection 对象,但是无法直接获取 Terminal 对象。但是,这并不重要。因为我们可以通过即时的事件来得到。又或者通过本地对象来得到,例如 Cisco CCM 实现的 CiscoCall ,我们就可以得到呼叫方和被呼叫方的 Terminal。

  噢,似乎 JTAPI 并不复杂。。。实际上,这只是个开始而已,正如紫霞猜不出结局那样。JTAPI 的麻烦与复杂之处在于,其开发过程是事件驱动的。所有的事件,几乎都是并发事件。不同的事件对应特定的情景,情景中的各种对象都有着自己特定的状态。下面简单介绍一下 JTAPI 在开发内容与注意事项。

2、JTAPI 开发(以Cisco JTAPI 为例

  2.1 拨号呼叫流程

  正如上面所说,JTAPI 的开发是事件驱动型开发。我们要介入呼叫过程,必须要接入和侦听呼叫过程所产生的事件。所以,要学习 JTAPI 的开发,首先就要看呼叫流程,下面以 Core Control Extention 为例(JTAPI Core 过于简单):

                         JTAPI 开发入门 (一)_第5张图片

  • 首先深呼吸,无论是 Address、Terminal 还是 Call ,都应该处于可用状态(IDLE)。
  • 拿起话简(Established)时,会依次产生 Call, Connectioin, TerminalConnetion 之类的逻辑对象,同时发出 N 多事件。
  • 拨号。产生按键事件,我们可以获取所按的号码。。。Call Center 通常用来接收客户选择。
  • 振铃(Alerting)。振铃事件包括 Address 层面(即 Connection)和 Terminal 层面(Terminal Connection)
  • 接听(Established)。拿起话简。
  • 通话(Talking)。处于通话状态时,我们甚至可以使用 Cisco RTP 来获取通话语音流,又或者播放语音提示。
  • 挂机(Drop / Disconnected)。又是 N 多事件
  • 结束

  2.2 开发基本流程思路

  要开发一个 JTAPI 应用,可以遵循下面的方法进行学习与开发:

  • 首先要明确应用的工作流程,如果能画状态图或流程图最好。
    *)是开发一个统计每天拨号次数的应用,还是录音软件,还是发现对方在黑名单就挂断的应用。不同的应用,对于事件的获取与处理是不一样的。
  • 呼叫过程中,JTAPI 会以事件广播的方式,向应用通知呼叫过程和呼叫状态。(Observer)
  • 应用的操作或流程动作,只能分散到各种事件中进行。这也为什么建议画状态图和流程图。因为在程序中,不那么容易直观了解工作流程
  • 很多情况(情景)下,我们只能在特定的事件中,才能获取对象(如 Call, Terminal等)特定和即时状态。
  • 事件的通知往往是并发,要注意状态对象的状态保护。

  2.3 开发过程中的常用类

   下面例出开发过程中常用的类及其在 Cisco 中的实现要点:

  • Provider

    ○ 这是 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 。。。等等

  • ProviderObserver

    ○ 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 : 同上

       等等。。更加细致的通知事件

  • Call

    ○ 呼叫对象,包含 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 等信息 。(例如,踢人那个爽。。)


(待续)





你可能感兴趣的:(Cisco,JTAPI)