大家用過Google Talk嗎?它是Google推出的一個IM,通訊協(xié)議是我們熟悉的Jabber協(xié)議。我通過這篇文章給大家簡單介紹一下如何利用ECF實(shí)現(xiàn)一個Google Talk客戶端。源代碼下載:
http://www.tkk7.com/Files/reloadcn/Chat.rar1.準(zhǔn)備工作先下載ECF:
www.eclipse.org/ecf為了能夠測試我們這個客戶端是否能正常運(yùn)行,我們還需要下載一個Goolge Talk客戶端:
www.google.com/talk當(dāng)然,我們想要登陸Google的服務(wù)器必須擁有一個GoogleMail帳號,由于現(xiàn)在GoogleMail帳號不是隨便申請的,需要GoogleMail用戶推薦才能申請,但也能通過一些網(wǎng)站進(jìn)入GoogleMail申請頁面,大家可以上網(wǎng)搜索一下,我在這里就不多說了。

我們要建立一個Google Talk的客戶端,需要了解一些ECF的知識。大家可以去Eclipse主站獲得更多的信息。
2.建立一個RCP Mail? Example
我們先選擇創(chuàng)建Plugin Project,取名為“Chat”,當(dāng)?shù)较驅(qū)ы摰牡诙摰臅r候,注意在“Would you to create a rich client platform”選項(xiàng)選擇“yes”,這樣確保你創(chuàng)建的是一個RCP工程,見下圖:

當(dāng)?shù)阶詈笠豁摰臅r候,選擇Mail Template:

完成向?qū)Ш笪覀儗玫揭粋€簡單的RCP工程。
3.登陸的代碼
1)連接前工作
ECF是一個基于Eclipse的通訊平臺,它其中一部分實(shí)現(xiàn)了Jabber協(xié)議。ECF有一個ClientContainer概念,其實(shí)就相當(dāng)于一個維護(hù)客戶端的對象,它具有連接、斷開連接服務(wù)的方法,并且能夠添加一些通訊中的事件監(jiān)聽器。所以,我們創(chuàng)建Google Talk客戶端首先就要擁有這么一個對象,而且它在整個程序生命周期中是唯一的。
讓我們修改一下ChatPlugin中的代碼:
首先,我們在這個類里增加一個私有變量clientContainer,并且給他加上Getter、Setter方法:
XMPPClientSOContainer?clientContainer;
????public?XMPPClientSOContainer?getClientContainer()?{
????????return?clientContainer;
????}
????public?void?setClientContainer(XMPPClientSOContainer?clientContainer)?{
????????this.clientContainer?=?clientContainer;
????}
OK,試想一下,當(dāng)我們在登陸Google服務(wù)器的時候才會去使用這個clientContainer去連接服務(wù)器,而且我們登陸的用戶信息是需要保存下來的,以供后面的代碼訪問,所以這個clientContainer的生成方式應(yīng)該是Lazy的,并且我們還需要建立一個我們登陸帳戶的變量:
????private?ID?userID;
????public?ID?getUserID()?{
????????return?userID;
????}
????public?void?setUserID(ID?userID)?{
????????this.userID?=?userID;
????}
ECF中針對用戶的信息是用ID來表示的,它是一個接口,ECF已經(jīng)實(shí)現(xiàn)了一個XMPPID,正好是我們Jabber帳戶需要的。
clientContainer有一個connect方法去登陸服務(wù)器,而且在連接后不再具有其他什么動作。讀者會問:那什么時候通知我們連接成功呢?并且用戶在服務(wù)器端的好友怎么獲得呢?
clientContainer只負(fù)責(zé)連接,上述的那些事情都屬于在連接服務(wù)器過程中或者連接后,服務(wù)器反饋給客戶端的信息,這些信息需要我們給clientContainer設(shè)置監(jiān)聽器去捕獲。
其中有一個監(jiān)聽器名為ISharedObjectContainerListener,這個監(jiān)聽器能夠捕獲一些在連接過程和斷開連接過程中的事件,比如SharedObjectConnectedEvent (連接成功事件)、SharedObjectDisconnectedEvent (斷開連接成功事件),如果我們需要在客戶端連接上服務(wù)器后做點(diǎn)什么,那這個監(jiān)聽器是必須的。
clientContainer.addListener(
??????????????????new?ISharedObjectContainerListener()?{
???????????????????public?void?handleEvent(IContainerEvent?evt)?
???????????????????????if?(evt?instanceof?ISharedObjectContainerConnectedEvent)?{
?????????????????????????????????// 連接服務(wù)器成功后做點(diǎn)什么呢?
??????????????????????? }
???????????????????????if?(evt?instanceof?ISharedObjectContainerDisconnectedEvent)?{
???????????????????????????????? // 斷開服務(wù)器成功后做點(diǎn)什么呢?
????????????????????????}
???????????????????}
???????????????????},?null);
2)開始連接服務(wù)器我們看看clientContainer有一個connect方法。
這個方法需要有兩個參數(shù):用戶的ID、連接上下文
用戶ID我們剛才已經(jīng)說過了,它是ECF提出的一個概念,我們可以通過IDFactory生成它:
userID?=?IDFactory.getDefault().makeID(
????????????????????????????????????????clientContainer.getConnectNamespace(),
????????????????????????????????????????getUserName());
大家發(fā)現(xiàn)了嗎,上面代碼中的makeID方法需要兩個參數(shù),一個參數(shù)我們可以從clientContainer獲得,它是連接名字空間,我的理解是某種協(xié)議。第二個是用戶名,這個參數(shù)在我們這里是Google Talk的帳號,也就是GMail帳號,但是目前我們還沒有辦法從外部獲得,這我會在下面的內(nèi)容中提到,到時候就可以將這個程序串起來,大家現(xiàn)在可以把它看作已經(jīng)具備某些值。
好,我們已經(jīng)有了ID,現(xiàn)在看看什么如何創(chuàng)建上下文。連接上下文其實(shí)很簡單,我們可以這樣理解:就是在我們連接的時候,clientContainer會向客戶端所取一些相關(guān)的信息,比如nikename,password,這樣理解起來就不麻煩了,而且在我們的這個Google Talk客戶端中,它也只會向我們索取password和username,來看看我們代碼就更清楚了:
clientContainer.connect(userID,?new?IConnectContext()?{
???????????public?CallbackHandler?getCallbackHandler()?{
???????????????return?new?CallbackHandler()?{????
?????????????????????public?void?handle(?Callback[]?callbacks)throws?IOException,
????????????????????????????????????????????????????????UnsupportedCallbackException?{
?????????????????????????????if?(callbacks?==?null)return;
???????????????????????????????for?(int?i?=?0;?i?<?callbacks.length;?i++)?{
?????????????????????????????????????if?(callbacks[i]?instanceof?NameCallback)?{
??????????????????????????????????????NameCallback?ncb?=?(NameCallback)?callbacks[i];
??????????????????????????????????????ncb.setName(getUserName());
??????????????????????????????????????}?else?
????????????????????????????? if?(callbacks[i]?instanceof?ObjectCallback)?{
?????????????????????????????????ObjectCallback?ocb?=?(ObjectCallback)?callbacks[i];
??????????????????????????????????ocb.setObject(password);
?????????????????????????????????}
????????????????????????????????????????????????????????}
????????????????????????????????????????????????????}
????????????????????????????????????????????????};
????????????????????????????????????????????}
????????????????????????????????????????});
到目前為止,我們已經(jīng)完成了連接這個環(huán)節(jié),我們將這些代碼都封裝到ChatPlugin的login方法中,到時候通過外部的操作好調(diào)用。