線路協定
此頁面描述了邏輯 OpenWire 協定,適用於使用 Java 以外的語言(例如 C# 或 C 原生用戶端)開發用戶端的用戶。請注意,OpenWire 設計旨在實現最佳效能和功能;它是 ActiveMQ Classic 內部使用的協定。如果您想要一個更簡單的協定來開始使用跨語言用戶端,請嘗試 Stomp,它專為易於實作而設計,因此很容易支援許多用戶端。
協定概述
ActiveMQ Classic 的用戶端將交換 Command 物件(遵循命令模式)。我們將描述這些命令是如何交換的…
該協定大多使用單向訊息傳遞(發送後不理會)來傳遞大多數類型的命令 - 但有時會使用 RPC(請求、回應)訊息傳遞。我們將清楚地指出 RPC 的情況。
建立連線
用戶端必須發送一個 ConnectionInfo 命令,其中包含機器、主機名稱、使用者名稱、密碼,最重要的是用戶端希望使用的唯一 clientId 的詳細資訊,然後等待有效的 Response 後才能繼續。clientId 必須使用唯一的字串產生器產生。
傳送訊息
建立連線後,您需要建立一個邏輯 MessageProducer。這涉及到發送一個 ProducerInfo 命令,其中包含唯一的 producerId、sessionId 和 clientId(連線 ID)。
從那時起,您可以隨時發送 Message 命令,前提是您在訊息中加入 clientId、sessionId、producerId 以及需要的 transactionId(請參閱下面的交易部分)。
消費訊息
命令會傳遞到您的輸入套接字以供消費。其中一些將是先前 RPC 的 Response,其餘的將是傳入的訊息以供分派。
若要開始消費訊息,您必須發送一個 ConsumerInfo 命令,其中包含 clientId、sessionId 和唯一 consumerId 的詳細資訊。從那時起,您將收到包含其目標 consumerId 的輸入訊息。
若要確認訊息,請將 MessageAck 發送到伺服器(單向)。在 MessageAck 中填寫 consumerId、sessionId、clientId 和任何 transactionId 的詳細資訊。
使用 Responses
當您建立連線、生產者和消費者時,您將收到 Response 以指示請求的狀態(例如是否成功或失敗)。由於協定是異步的,您可以接收到順序錯亂的 Response 命令;您可能有多個執行緒使用相同的連線/套接字並行發送命令。
因此,在多執行緒用戶端中,通常會有一些相關性 Map 來將 Command ID 與 Response ID 匹配,以便您可以知道哪個執行緒中的哪個操作成功或失敗等等。請參閱 Java 中的 Transport 實作,以了解我們是如何做到這一點的。例如,請參閱 ResponseCorrelator
ID
目前的要求是,用戶端必須自動產生用戶端、會話、生產者和消費者 ID,這些 ID 通常是字串,並且旨在全域唯一。同樣,每個 Command 都有自己的整數計數器 ID,用戶端使用它來將請求關聯到回應;用戶端通常會使用遞增的滾動計數器來處理這些。
關閉生產者、消費者、會話、連線
若要關閉資源,請發送一個 RemoveInfo 命令,其中包含生產者、消費者、會話、連線等的正確 objectId。
JMS 交易
每個交易會話都會產生一個唯一的交易 ID,該 ID 會在任何交易訊息上傳遞。若要開始、提交或回滾,用戶端應單向發送 TransactionInfo 命令(不會產生 Response)。
在提交或回滾之後,應產生新的交易 ID 並發送新的啟動 TransactionInfo。
任何傳送的訊息或訊息確認也應傳播交易 ID。
XA 交易
與上述相同,但使用 XATransactionInfo。另外,我們會傳遞 XAid 而不是 transactionID。
最後的想法
如果您對協定的某一部分有任何疑問,找出發生情況的最簡單方法是查看 JMS 用戶端程式碼。特別是查看 ActiveMQSession 的程式碼,其中包含幾乎所有上述邏輯。當命令被傳送到訊息代理時,請特別注意對 syncSendCommand() 和 asyncSendCommand() 的呼叫