[訊息論壇] ICE Messaging Forum
塗能宇 / 郭漢丞
<實作篇> 在 VB 上利用 iPush®
開發 Internet 即時訊息工具 (下)
我們完成上了禮拜的設定操作之後,接下來您只要動動滑鼠,跟著步驟將所附文字檔中的內容一一複製到表單中,就可以完成這個禮拜的實作了。
如果您已經忘記了上一期的內容,請按此連結上期文章,並進行相關檔案之下載。
我們上期已經將 XiPush2 控制項,拖曳到表單中,現在可以開始使用此 iPush®
ActiveX 元件 了。
一個完整的 iPush® 客戶端,必須具備傳送和接收資料的功能。接著我們就從連線部分開始處理。
我們將連線部分的資料設定,整個放在 FillLoginInfo() 中處理。它會將所有連線所需要的資料,設定到
XiPush21 控制項中。請將 FillLoginInfo() 的函式,複製到 Form.Show 函式下。
|
圖二、處理連線所需資訊的函式
FillLoginInfo() |
iPush® 提供了兩種網路連線方式:TCP 以及 UDP,我們先使用 TCP
來進行連線,並在 Command1 Connect 的 On_Click 事件,加入以下程式碼。
TCP 提供了一個穩定的連線方式,讓資料能夠透過 Internet 正常的傳送及接收。請在 [TCP Connect]
按鈕的 Command1_Click() 事件中,加入以下的程式碼,或是將本期所附的文字檔 (code_for_weekly.txt)
打開,將相對的程式碼複製到 Command1_Click(),利用這幾行程式碼,我們就可以與 iPush®
Server 建立 TCP 連線。
當 rtn 傳回值大於 1 的時候,就代表連線成功,同時將連線訊息及對應的狀態碼顯示在 Label 物件中。小於
1 代表連線失敗,也會印出相對應的錯誤碼。關於訊息代碼的說明,可參閱 iPush®
V2 的 ActiveX API Programming Guide (您可以在 ICE
Developer Center / Download 區下載 ActiveX.zip 取得該 PDF
文件)。
要切斷與 iPush® Server 的連線很簡單,只要呼叫 ipushDisconnect()
就可以完成切斷連線的工作。請在 Command2 的 OnClick 事件中,加入以下程式碼。
連線程式完成後,我們先使用 Channel 的方式傳送資料。傳輸資料的部分實際上只有一行,就是:XiPush21.ipushSendChannelData
a, b
這幾行的功用就是將 textData 的文字資料及 Channel 名稱,轉成 Variant 資料型態後送出去。
然後我們要處理的,就是接收資料的部分。這一個部分有兩個步驟,第一步是先向 iPush®
Server 訂閱 Channel。第二 步是由 iPush® Server 主動將已訂閱的即時訊息推播
(Push) 給訂閱者接收。
第一步訂閱的方式如下圖:
|
圖六、在
Subscribe Channel 中加入的程式碼 |
第二步是由 iPush® ActiveX Callback 函式完成。在這個範例中,我們總共實作了三個
Callback 函式 ,分別是:
-
XiPush21_CommandMsg():使用在顯示系統連線訊息上
-
XiPush21_SetChannelData():使用在接收
Channel 資料上
-
XiPush21_SetSubjectData():使用在接收
Subject 資料上
註:一般我們是呼叫元件來幫我們完成想要完成的工作,若是元件想要主動通知程式某個事件發生時,就必須透過所謂的
Callback 方式執行 ;Callback 函式是實踐 Event-driven 軟體設計的重要手段。
|
圖七、由
iPush® API 呼叫應用程式的 Callback 函式 |
所以在完整程式的最下方,所寫作的三個函式,就是提供 iPush® ActiveX
API 的 Callback 函式使用 ,分別用來接收系統、Channel、Subject 所傳送的訊息。
在 SetChannelData() 這個 Callback 函式中,會回傳兩個值,分別是:
-
string 型態的 channel 資料
-
variant 型態的 data 資料
iPush® API 另外提供了一個 ipushVar2Str 函式,可以將 variant
格式的資料,轉換成 String 型態的資料。我們將 收到的訊息,顯示在 Label4 和 Label5 的內容中,Label4
顯示的是 Channel 的頻道名稱字串 (Channel ID)。請將所附範例文字檔的 Call Back 函式部分,複製到表單最下方即可。
若您需要,可以先測試連線功能,先按下工作列上的執行鍵,執行目前的程式。接著執行下載 ZIP 所附的另一個 Project1.exe
檔,開啟兩個連線程式。
輸入所有的連線資訊後,按下 [TCP Connect] 鈕執行系統連線的工作。由於 Channel 的分類是由
4 個 Byte 組成,所以你可以輸入 YEAH 或 ABCD 等四個 bytes 以內的資料當成 Channel
名稱。
我們先假設要收到 channel YEAH 的資料,先在使用者 b 視窗的 channel 文字方塊輸入 YEAH
後,按下 [Subscribe Channel] 鈕。
接著在使用者 a 視窗的 data 文字方塊中輸入想傳送的資料,按下 [Send Channel] 鈕就可以完成資料傳送的工作。
|
圖十、
使用者 a 視窗輸入要傳送的
Channel 資料 |
|
圖十一、
使用者 b 視窗接收到的
Channel 資料 |
在這邊我們可以先休息一下,在處理完 channel 的訊息收送後,接下來的工作就輕鬆了。您可以泡一杯咖啡,看一下有關
UDP 的介紹,再來完成下面 Subject 訊息的收送實作。
相對於 TCP,UDP 是一種比較精簡的傳輸方式,在 LAN 上也許還可以,但若是要用在 Internet 上,恐怕就比較不適合
(因為大部分的 ISP 或企業網管,會阻擋 UDP 封包)。
使用 ipushUDPConnect() 來建立 UDP 連線,程式敘述跟 TCP 連線是一樣的。
將程式碼複製到 [UDP Connect] 鈕的 Command11_Click() 事件下。相關的程式碼,您只需將
ipushTCPConnect 改為 ipushUDPConnect 即可。而 iPush®
的 UDP 斷線機制,和 TCP 完全相同,所以不需要 修改即可直接套用。
在這裡,一定很多人好奇什麼是 Subject? 一個 Subject Name 可能長得像這樣子:
ice.office.product.pm
由左到右的階層式命名,可以解釋成 ice 公司 office 裡的 product 部門的 pm 要訂閱接收這個訊息。這樣比指定一個叫
ABCD 或是 0x1f 的 Channel ID 要來得讓人容易了解。 除了比 Channel 容易了解外,Subject
Name 可高達 224 Bytes 的長度,也是另外一個優點。
接下來我們要完成的,就是如何傳送及接收 Subject 定址的訊息、及實作 Subject 的 Callback
函式。
請分別雙擊 [Subscribe Subject] 與 [Unsubscribe Subject] 按鈕後,在
On_Click 事件中,分別加入以下敘述:
|
圖十三、訂閱
Subject 程式碼 |
|
圖十四、取消訂閱
Subject 程式碼也只要一行 |
| 接收 Subject 資料的 Callback 函式 |
Subject 接收訊息部分,亦是由 iPush® ActiveX Callback
函式完成的。關於 Callback 的說明,您可以參考上述 Channel 的內容。在這個範例中,Subject
訊息接收的 Callback 函式為 SetSubjectData():
|
圖十五、XiPush21_SetSubjectData():使用在接收
Subject 訊息 |
我們將接收的 Subject 訊息,顯示在 Label9 標籤中。
我們使用 ipushSendNPSubjectData() 這個方法來傳送 Non-persistent Subject
訊息,而傳送的 參數主要包含兩樣:一個是 String 格式的 Subject Name,另一個是 Variant
格式的訊息內容。
接著我們就類比上述 Channel 訊息傳送做一番測試,看看是不是做好的 Subject 收送機制可以正常的運作。可以讓使用者
a (如下圖),利用 Subject ice.ipush.pm 傳送訊息給已經訂閱 ice.ipush.pm 的使用者
b:
|
圖十六、使用者
a 利用 Subject 來傳送訊息 |
| Persistent (持續性)訊息與 Durable
(持久性)訂閱 |
接下來,我們要進入另一個主題,就是有關訊息保證送達 (Guaranteed Message Delivery)
的運作。
Durable Subscription (持久性訂閱) 是訊息中介軟體 (MOM) 於訊息保證送達規範的其中一項特性。Durable
Subscription 可 以實施在 Subject Addressing 的 Pub/Sub 與 P2P 兩種訊息傳遞模式上。
訂閱者可針對某一特定的 Subject,選擇成為一般訂閱者,或是持久性的訂閱者。
Durable Subscription 相關的 iPush® 函式分別是:
當訊息發送者將 Persistent (持續性) 訊息送給 iPush® Server
時,若持久性訂閱者 楚於離線的狀態,則 iPush® Server 會將該訊息儲存起來。待下次該訂閱者再上線,並以同一
Durable Name 訂閱同一 Subject,iPush® Server 就會自動將訊息傳送給該訂閱者。
有了這樣的機制,訂閱者將不會因為離線的關係,而錯失應該接收到的訊息。在 Pub/Sub 模式下 Persistent
(持續性) 訊息 發送的函式為:
- 傳送訊息的 ipushSendPSubjectData()
傳送 Persistent 訊息只需要使用 ipushSendPSubjectData() 就可以完成工作,不過在傳送時。還可以進一步指定
該 Persistent 訊息在 iPush® Server 上停留的時間長短 (TTL)。相關的說明,可以參見第
59 期的電子週報。若沒有特別指定,系統將會依照預設的一天時間值保存資料。
|
圖十七、請將傳送
Persistent 訊息的方式加入 Command8_Click() 中 |
當傳送端傳送 Persistent 訊息給 iPush® Server 時,若先前有使用者以
Durable 方式訂閱同一 Subject,不管該訂閱者是在線還是離線,該訊息都會先被儲存起來。
接收端選擇了 Durable (持久性) 訂閱,給予 Durable Name,即使是離線,還是可以在重新上線後,再次進行訂閱,就可以接取先前為其留存的
Persistent 訊息了。
我們利用 ipushSubDSubject() 來完成 Persistent 訊息的傳送:
|
圖十八、將
Durable 訂閱的程式碼複製到 Command7_Click() 中 |
|
圖十九、將取消
Durable 訂閱的程式碼加入 Command10_Click() 中 |
下次同一使用者再連線後,輸入與先前訂閱相同的 Subject Name 以及 Durable Name 名稱,就可以收到離線期間給他的
Persistent 訊息了。
|
圖二十、先讓使用者
b 進行 Durable 訂閱,除了 Subject Name (subject 欄位) 外,還需加上
Durable Name (durable name 欄位) |
|
圖二十一、讓使用者
a 發送 Persistent 訊息到使用者 b 已經訂閱的 Subject |
當接收端連線狀態無法確定,或是連線狀態不穩定時,就可以使用 Persistent (持續性) 傳送,以及 Durable
(持久性)訂閱的方式 ,以確保資料能夠正確無誤地傳送及接收。
|