[訊息論壇] ICE Messaging Forum
蔣居裕
<技術篇> iPush® Server V2 訊息保證送達技術剖析
有同時使用過 ICQ 與 MSN Messenger
這兩個傳訊軟體的讀者就會知道,對於已經離線
(Offline) 的朋友,在 ICQ
中,您是可以發送離線訊息給他的,但 MSN Messenger
則否。這差別就在 Server
會不會幫接收者儲存離線訊息。
像 ICQ 這樣會幫使用者儲存離線訊息,待其下次上線
(Online) 後,再傳送給他的傳訊功能,即是訊息保證送達
(Guaranteed Message Delivery) 的一種應用。
iPush®
Server V2
很重要的大區塊功能增加,即是有了訊息保證送達的能力。以下是我們對這個能力的技術說明。
Pub / Sub 與 P2P
兩種訊息傳遞模式均能啟用訊息保證送達的能力;但當然,在
P2P 下,只有一位 Subscriber 會收到該保證送達之訊息
要能夠應用 iPush®
Server V2
訊息保證送達的能力,必須具備下列三個要件:
-
保證送達只針對 Subject 訊息;Channel
訊息無此能力。
-
發送者必須傳送 Persistent
(持續性) 訊息給 iPush®
Server。
-
接收者必須向 iPush®
Server 進行 Durable (持久性) 訂閱。
我們來看如下的作業示意圖:
| 
|
|
圖一、iPush®
V2 訊息保證送達作業示意圖
|
作業流程步驟敘述如下:
-
發送者 (Publisher) 針對某一
Subject 傳送 Persistent 訊息給 iPush®
Server。叫用函式為 ipushSendPSubjectData()
或 ipushSendPQueueSubjectData()。
-
iPush®
Server 收到該 Persistent 訊息後,會將其儲存起來 (儲存介質為
File 或 Database)。
-
iPush®
Server 成功儲存後,會送一個回應訊息 (Acknowledgement)
給發送者。
-
iPush®
Server 根據 Subscription Mapping,將儲存的 Persistent
訊息,主動推播給上線的 Durable 訂閱接收者。Durable
訂閱接收者為先前叫用函式 ipushSubDSubject()
訂閱該
Subject 的使用者。
-
收到該訊息後,該接收者會送一個回應訊息
(Acknowledgement, ACK) 給 iPush®
Server。
-
iPush®
Server 收到回應訊息後,即會將該遞送完成的訊息,從儲存介質中移除。
這樣的作業流程,非常的直覺易懂,但其中的某些環節,還是值得深入探究,以便
Developer 在開發應用時,可以更加貼切。
而前三個步驟與後三個步驟各自獨立運作,讓發送者與接收者以
iPush®
Server 隔開不相關,體現的即是 Loosely-coupled (低耦合系統),與
Asynchronous Programming (非同步程式設計) 的精神。
我們繼續深入各環節討論下去。
在步驟 2,iPush®
Server 會根據收到 Persistent 訊息時的叫用函式種類,來決定該訊息是處於
Pub/Sub 還是 P2P
傳遞模式,來決定是要儲存一份還是多份。
若是處於 Pub/Sub 傳遞模式
,則還要加上當時的 Subscription Mapping,來決定實際儲存的份數,以便每一位
Subscriber 都可以收到一份該訊息。
在步驟 3,我們可以指定送
Persistent 訊息出去後多久的時間內,若是 iPush®
Server 沒有 ACK 回應,就判定為 Timeout。 ActiveX API
利用 Property ackTimeout
來設定 ACK Timeout 時間。
預設
ackTimeout 為 10000 ms,即 10
秒。
Java Class API
利用函式 ipushSetAckTimeout()
來設定 ACK Timeout 時間。如下所示: public long
ipushSetAckTimeout(int index, long
timeout) 其中的 timeout 即為 ACK
Timeout 時間,屬 long 資料型態,單位為 ms (毫秒)。若不叫用此函式,系統預設為 10000 ms,即 10
秒。
有別於一般的訂閱方式 (Non-durable
Subscription),在進行 Durable Subscription (持久性訂閱)
函式呼叫時,除了給予要訂閱的 Subject Name
外,還要再多給一個 Durable Name (最大長度為 224
個字元),以便讓 iPush®
Server 進行 Subscription Mapping 作業。 當使用者對
iPush®
Server 進行 Durable Subscription
後,即使該使用者離線,在這期間只要是有其訂閱
Subject 的 Persistent 訊息到來,iPush®
Server
還是會為其進行儲存的作業。待其下次上線,再次進行同一
Subject,同一 Durable Name 的 Durable Subscription,即會將屬於他的訊息推送過去給他。 相關函式呼叫說明如下: <訂閱> ActiveX API
只要是叫用 Durable Subscription
的函式,就必須在參數中給定 Durable Name,如下 ipushSubDSubject()
所示者: void ipushSubDSubject(BSTR
subject, BSTR name) 其中的 name 即為
Durable Name,屬 BSTR 資料型態,其最大有效長度為 224
個字元。
Java Class API
只要是叫用 Durable Subscription
的函式,就必須在參數中給定 Durable Name,如下 ipushSubDSubject()
所示者: public void ipushSubDSubject(int
index, String subjects, String name) 其中的 name 即為
Durable Name,屬 String 資料型態,其最大有效長度為 224
個字元。
<取消訂閱> ActiveX API
與訂閱對應,也一樣要在參數中給定要取消的
Durable Name,如下 ipushUnsubDSubject()
所示者:
void ipushUnsubDSubject(BSTR
subject, BSTR name)
其中的 name 即為要取消訂閱的
Durable Name,屬 BSTR 資料型態,其最大有效長度為 224
個字元。
Java Class API
與訂閱對應,也一樣要在參數中給定要取消的
Durable Name,如下 ipushUnsubDSubject()
所示者: public void ipushUnsubDSubject(int
index, String subjects, String name) 其中的 name
即為要取消訂閱的 Durable Name,屬 String
資料型態,其最大有效長度為 224 個字元。
<訊息接收處理> 接收者隨
Subject 訊息接收到的 durableName 參數值 (ActiveX Event) 或 durname
參數值 (Java interface) 可以得知訊息的 Durable Name。
ActiveX API
iPush®
Server 推送 Subject 訊息給訂閱者接收時,接收者的 API
會丟出 Event SetSubjectData(),其中的 durableName
參數值即是該訊息的 Durable Name,如下所示者: SetSubjectData(BSTR
subject, BSTR durableName, VARIANT* data, long connId, long
msgId) 其中的 durableName 為 BSTR
資料型態;若其長度為 0,就表示這是一個Non-durable
Subscription 訊息。
Java Class API
iPush®
Server 推送 Subject 訊息給訂閱者接收時,接收者的 API
會丟出 interface iPush2MsgListener 中的 Method onSubjectMessage(),其中的 durname
參數值即是訊息發送者的 Durable Name,如下所示者: public void onSubjectMessage(int
ipushno, String subject, String durname, byte msg[], int msglen, int
CID,
long MsgID) 其中的 durname 為 String
資料型態;若其長度為 0,就表示這是一個Non-durable
Subscription 訊息。
在步驟 6,iPush®
Server
在收到接收者的回應訊息後,即會將先前為該接收者儲存的
Persistent 訊息移除。 另一個 iPush®
Server 會自儲存介質移除 Persistent
訊息的時機,即為該訊息的有效期限 (Time-To-Live)
已到。詳情請參考上期電子報。
| 當 Durable Subscription 對上
Non-persistent 訊息 |
雖然系統也會儲存 Non-persistent
訊息,但因為 iPush®
Server 在傳送 Non-persistent 訊息給 Durable Subscription
使用者時,並不會等待一個個的 ACK 回應,所以若是
Non-persistent
訊息過多,或是連線情況不佳,可能會被 iPush®
Server 視為壅塞,進而丟棄處理。 所以在開發設計應用系統時,應該避免使用
Durable Subscription 來接收 Non-persistent
訊息,以免有意想不到的結果產生。 結論就是:要應用
iPush®
Server V2
的訊息保證送達能力來實作應用系統,就切記訊息收送的黃金組合為: Guaranteed
Delivery = Persistent Message Publishing + Durable Subscription |