對象包分析:JTAPI的對象包除了核心包以外都提供自己獨特的功能。核心包比較特殊,按照物件導向的理論,核心包是其它包的父類。核心包只能夠提供最基本的電話功能,而其它對象包則是核心包的擴充。比如針對核心包中的對象Call,呼叫控制包有專門的對象CallControlCall,後者具有前者的所有屬性和方法,並在前者的基礎上添加了專門的屬性和方法。比如CallControlCall和Call都有方法connect(),而CallControlCall更有自己專屬的方法conference()、transfer()。簡單的說,實際上核心包的對象Call可以提供基本的電話功能,如撥出、接聽、掛機等。而呼叫控制包的對象CallControlCall不僅有基本的電話功能,還有特殊的會議電話、轉接電話、監聽電話等功能。同樣話務中心專用包的電話對象CallCenterCall也是一樣,它的特殊功能有預撥電話、得到使用者資料等方法。
3. 利用JTAPI搭建CTI程式
JTAPI電話模型樹
程式員在掌握利用JTAPI編寫CTI程式之前,首先得搞清JTAPI最基本的電話模型,這個模型是搭建CTI程式的基礎,它可以以樹狀結構表現出來(如)。
可以說,程式員心裡有了這幅樹狀電話模型圖,從簡單的撥出電話到複雜的兩路來話相互切換功能都可以很方便的實現。
構成電話模型圖的元素都是JTAPI核心包的主要對象,每個對象都代表了CTI領域中的一個物理或邏輯的實體。由圖可知,這些實體之間有著相互的聯絡。利用每個實體的功能以及實體之間的關係,程式員就可以組合出各種各樣的CTI程式。下面簡單介紹電話模型中涉及的最主要的幾個實體。
Provider是對和CTI技術相關的硬體裝置的一個抽象,它可能代表工控機上插的一塊板塊,也可能代表一台複雜的DEFINITY ECS。Provider把具體的硬體裝置和程式員隔離開來,使程式員不必懂得複雜的硬體裝置。這有些類似於資料庫編程時遇到的ODBC概念,資料庫程式員不必知道背景資料庫是ORACLE還是簡單的ACCESS。程式員只需知道經過初始化,就能得到一個可以訪問後台資源的執行個體即可。利用Provider ,可以輕易的實現CTI程式和硬體的無關性。程式不變,背景PBX可以從Lucent Technologies的產品換成Nortel的產品。
CALL是對一次呼叫過程進行抽象,它的屬性記錄了這個呼叫目前的資訊,調用Call的方法,可以引導這個呼叫的發展。
簡單的說,Address Object是對電話號碼的抽象。它是對一部邏輯電話的描述,和它對應的不是一部物理電話,所以一個Address Object可能對應了多個物理話機。
Terminal Object描述了一部具體的物理話機和其相關的屬性。每個Terminal Object至少存在一個Address Object與之對應。
一個Connection Object是對Call Object和Address Object之間的通訊串連的抽象。通過對Connection Object的屬性查看,可以分析出當前Call Object與Address Object的串連狀態資訊。Connection Object的狀態有IDLE、ACTIVE、RINGING、DROPPED等等。
軟電話功能調用和電話訊息處理
利用JTAPI進行CTI應用程式的編寫,工作上可以分為兩個部分。首先是用戶端主動調用後台PBX資源,實現軟電話功能的調用;其次是用戶端對後台資源傳來的大量電話訊息進行分析,實現訊息分發與分揀。
利用Call Object能夠進行各種軟電話調用的工作,如call.connect()可以實現撥打一個電話;call. conference()可以實現與第三方會議一個電話;call.transfer()可以實現把接起的電話進行轉接到第三方的操作;利用諸如以上所述的種種方法,可以任意搭建出複雜功能的CTI應用。
JTAPI利用OBSERVER的概念來進行各種訊息處理。OBSERVER直譯過來是觀察者的意思,顧名思義,OBSERVER就是對每個呼叫對象進行“觀察”工作。它的工作流程是“綁定到專門對象���》觀察專門對象���》擷取專門對象的資訊��》分析並彙報專門對象的資訊”。
針對前文JTAPI對象樹提到的各種對象,都有專門的OBSERVER為之“服務”。比如對Provider,有ProviderObserver,它可以隨時彙報目前被監控的Provider的狀態,如Provider.OUT_OF_SERVCE, Provider.IN_SERVICE等等;針對Terminal,有TerminalObserver,它能彙報出一個Terminal的所有事件以及相關資訊,CTI應用中非常重要的資料主叫號碼、同步資料等就可以在這裡得到。類似的,還有AddressObserver、CallObserver等多種Observer。所有的Observer都是javax.telephony.observer的子類。
4. 應用執行個體分析
下面提供一個簡單的軟電話撥出程式碼。代碼分為“撥出”模組,以及“監控”模組。這兩個模組分別和前文提到的“ 用戶端主動調用後台PBX資源”,以及“用戶端對後台資源傳來的電話訊息進行分析”相對應。通過對這個例子的分析,我們可以很快掌握利用JTAPI開發CTI應用程式的基本思想。
4.1撥出模組
首先是“撥出”模組,這個部分的程式流程圖如所示,以下是程式碼分析。
import javax.telephony.*;
import javax.telephony.events.*;
import MyOutCallObserver;
//整個程式的結果是實現從電話4761111撥出到電話5551212
public class Outcall {
public static final void main(String args[]) {
// 產生一個Provider執行個體
Provider myprovider = null;
try {
JtapiPeer peer = JtapiPeerFactory.getJtapiPeer(null);
myprovider = peer.getProvider(null);
} catch (Exception excp) {
System.out.println("Can't get Provider: " + excp.toString());
System.exit(0);
}
// 利用Provider執行個體產生一個和電話4761111的Address執行個體
Address origaddr = null;
Terminal origterm = null;
try {
origaddr = myprovider.getAddress("4761111");
//得到這個Address上綁定的Terminial(物理話機執行個體)列表,取出第一個。
//這一操作,可以理解為對於電話4761111,有可能不止綁定了一部分機。
//如果有若干分機,任意取出一個可用的進行後續操作。
Terminal[] terminals = origaddr.getTerminals();
if (terminals == null) {
System.out.println("No Terminals on Address.");
System.exit(0);
}
origterm = terminals[0];
} catch (Exception excp) {
//處理異常;
}
//建立一個空的Call 對象
Call mycall = null;
try {
mycall = myprovider.createCall();
//在這個Call上綁定一個Observer,這個Observer可以
//對整個撥出過程進行訊息分析。(Observer的代碼下文有講解)
mycall.addObserver(new MyOutCallObserver());
} catch (Exception excp) {
//處理異常
}
//進行撥出,所需的資源有剛才得到的Address、Terminal、Call對象
//以及被叫號碼
try {
mycall.connect(origterm, origaddr, "5551212");
} catch (Exception excp) {
//處理異常
}
}
}
4.2訊息處理模組
下面對Observer的代碼進行簡單的分析
import javax.telephony.*;
import javax.telephony.events.*;
//類MyOutCallObserver實現了介面CallObserver的若干方法
//MyOutCallObserver對Call相關的各種事件進行了處理。
public class MyOutCallObserver implements CallObserver {
public void callChangedEvent(CallEv[] evlist) {
for (int i = 0; i < evlist.length; i++) {
//判斷是否得到有關Address的事件
if (evlist[i] instanceof AddrEv) {
//如果是有關於Address的事件,則利用這個事件獲得相關的Address執行個體
String name = null;
try {
Address addr = ((AddrEv )evlist[i]) getAddress();
//從這個Address執行個體擷取主叫號碼
name = addr.getName();
} catch (Exception excp) {
//處理異常
}
String msg = "Connection to Address: " + name + " is ";
//分析這個事件的具體類型並進行相應處理
//這個事件屬於“震鈴”事件,進行相應處理。
if (evlist[i].getID() == ConnAlertingEv.ID) {
System.out.println(msg + "ALERTING");
}
//這個事件屬於“來話接起”事件,進行相應處理。
else if (evlist[i].getID() == ConnConnectedEv.ID) {
System.out.println(msg + "CONNECTED");
}
//這個事件屬於“掛機”事件,進行相應處理。
else if (evlist[i].getID() == ConnDisconnectedEv.ID) {
System.out.println(msg + "DISCONNECTED");
}
}
}
}
}
可以看出,MyOutCallObserver能夠擷取任何與Call相關的事件,在MyOutCallObserver適當添加代碼,即可以實現對來話訊息進行捕獲、分析、以及處理。
5. 結尾
綜上所述,利用JTAPI可以方便的用JAVA搭建CTI程式。如果把JTAPI編寫的程式放置到APPLET中,就能夠輕鬆實現B/S模式的CTI應用程式。
華勝天成公司供稿,CTI論壇編輯 2001/05/29