OpenWire 版本 2 規範
連線能力 > 協定 > OpenWire > OpenWire 版本 2 規範
OpenWire 版本 2 不是最新版本。
本文參考的 OpenWire V2 已不是最新版本。本文中的格式和編碼規則對於後續的 OpenWire 版本仍然有效,但後續版本在 OpenWire 命令中定義了額外的欄位。本文中顯示的預設設定可能無法反映當前的預設值,請參閱此頁面以取得最新的預設 OpenWire 設定。
概述
OpenWire 用於將物件封送到位元組陣列,再從位元組陣列還原回物件。我們將封送的物件稱為命令。
TCP 網路連線會在資料流中看到多個背對背的命令。命令之間沒有任何分隔符號,並且大小可變。
+---------+ +---------+ +---------+
| command | | command | .... | command |
+---------+ +---------+ +---------+
編碼命令中使用的所有基本資料類型都以大端/網路位元組順序編碼。
基本類型和編碼
| | | | | |
+----------+ | +-----------+ | +-----------+ | +-----------+ | +-----------+ | +-----------+ | +-----------+
| byte | | | char | | | short | | | int | | | long | | | float | | | double |
+----------+ | +-----------+ | +-----------+ | +-----------+ | +-----------+ | +-----------+ | +-----------+
| 1 octect | | | 2 octects | | | 2 octects | | | 4 octects | | | 8 octects | | | 4 octects | | | 8 octects |
+----------+ | +-----------+ | +-----------+ | +-----------+ | +-----------+ | +-----------+ | +-----------+
| | | | | |
線路格式協商
OpenWire 具有可擴展性,它支援新增編碼選項,同時仍與協定的先前版本向後相容。每個 OpenWire 協定會話最初都以所有編碼選項關閉且命令封送器的版本 1 開始。兩個節點之間會交換初始的 WIREFORMAT_INFO 命令,以便啟用其他編碼功能。如果雙方都要求啟用編碼功能,則會啟用該功能。使用的命令封送器將是雙方都支援的最高版本。
+-------------------------+ +---------+ +---------+ +---------+
| WIREFORMAT_INFO command | | command | | command | .... | command |
+-------------------------+ +---------+ +---------+ +---------+
命令編碼
每個命令的編碼方式如下
命令編碼
[=If SizePrefixDisabled =]
[ option is not enabled. ]
[ +------+ ] +------+-------------------------+
[ | size | ] | type | command-specific-fields |
[ +------+ ] +------+-------------------------+
[ | int | ] | byte | (size-1) octects |
[ +------+ ] +------+-------------------------+
[========================]
欄位 | 描述 |
---|---|
大小 | 保存命令中後續位元組的數量 |
類型 | 命令類型識別碼 |
命令特定欄位 | 命令的資料。其編碼取決於使用的類型 |
如果命令類型沒有任何命令特定的內容,則大小將為 1。
在每個命令上加上大小前綴是為了協助非阻塞 IO 處理,以便接收器可以輕鬆判斷何時已接收到整個命令並且可以處理。但是,找出命令的大小需要在傳送器端進行額外緩衝,如果接收器正在執行阻塞 IO 則不需要。如果在交換 WIREFORMAT_INFO 資料包後啟用了 SizePrefixDisabled 選項,則每個後續的命令都不會加上大小前綴。
命令類型
類型識別碼 | 命令 |
---|---|
1 | WIREFORMAT_INFO |
2 | BROKER_INFO |
3 | CONNECTION_INFO |
4 | SESSION_INFO |
5 | CONSUMER_INFO |
6 | PRODUCER_INFO |
7 | TRANSACTION_INFO |
8 | DESTINATION_INFO |
9 | REMOVE_SUBSCRIPTION_INFO |
10 | KEEP_ALIVE_INFO |
11 | SHUTDOWN_INFO |
12 | REMOVE_INFO |
14 | CONTROL_COMMAND |
15 | FLUSH_COMMAND |
16 | CONNECTION_ERROR |
17 | CONSUMER_CONTROL |
18 | CONNECTION_CONTROL |
21 | MESSAGE_DISPATCH |
22 | MESSAGE_ACK |
23 | ACTIVEMQ_MESSAGE |
24 | ACTIVEMQ_BYTES_MESSAGE |
25 | ACTIVEMQ_MAP_MESSAGE |
26 | ACTIVEMQ_OBJECT_MESSAGE |
27 | ACTIVEMQ_STREAM_MESSAGE |
28 | ACTIVEMQ_TEXT_MESSAGE |
30 | RESPONSE |
31 | EXCEPTION_RESPONSE |
32 | DATA_RESPONSE |
33 | DATA_ARRAY_RESPONSE |
34 | INTEGER_RESPONSE |
40 | DISCOVERY_EVENT |
50 | JOURNAL_ACK |
52 | JOURNAL_REMOVE |
53 | JOURNAL_TRACE |
54 | JOURNAL_TRANSACTION |
55 | DURABLE_SUBSCRIPTION_INFO |
60 | PARTIAL_COMMAND |
61 | PARTIAL_LAST_COMMAND |
65 | REPLAY |
70 | BYTE_TYPE |
71 | CHAR_TYPE |
72 | SHORT_TYPE |
73 | INTEGER_TYPE |
74 | LONG_TYPE |
75 | DOUBLE_TYPE |
76 | FLOAT_TYPE |
77 | STRING_TYPE |
78 | BOOLEAN_TYPE |
79 | BYTE_ARRAY_TYPE |
90 | MESSAGE_DISPATCH_NOTIFICATION |
91 | NETWORK_BRIDGE_FILTER |
100 | ACTIVEMQ_QUEUE |
101 | ACTIVEMQ_TOPIC |
102 | ACTIVEMQ_TEMP_QUEUE |
103 | ACTIVEMQ_TEMP_TOPIC |
110 | MESSAGE_ID |
111 | ACTIVEMQ_LOCAL_TRANSACTION_ID |
112 | ACTIVEMQ_XA_TRANSACTION_ID |
120 | CONNECTION_ID |
121 | SESSION_ID |
122 | CONSUMER_ID |
123 | PRODUCER_ID |
124 | BROKER_ID |
命令欄位編碼
所有 OpenWire 命令在編碼其欄位時都使用相同的演算法。該演算法限制命令使用以下類型的欄位
- Java 基本類型
- 字串
- 位元組陣列
- N 大小的位元組陣列
- Throwable
- 巢狀 OpenWire 命令
- 巢狀 OpenWire 命令陣列
- 快取的巢狀 OpenWire 命令
請注意,OpenWire 命令可以在其欄位中巢狀其他 OpenWire 命令。必須注意只封送命令的非循環圖形。
字串類型編碼
字串欄位可以為 null。如果為 null,則編碼為單個「0」位元組。
字串編碼
[=If not-null is 1===========]
+----------+ [ +-------+----------------+ ]
| not-null | [ | size | encoded-string | ]
+----------+ [ +-------+----------------+ ]
| byte | [ | short | size octects | ]
+----------+ [ +-------+----------------+ ]
[============================]
欄位 | 描述 |
---|---|
非 null | 如果字串不為 null,則為 1,如果字串為 null,則為 0 |
大小 | UTF-8 編碼字串的位元組數 |
編碼字串 | 字串的 UTF-8 編碼形式 |
位元組陣列類型編碼
位元組陣列欄位可以為 null。如果為 null,則編碼為單個「0」位元組。
位元組陣列編碼
[=If not-null is 1========]
+----------+ [ +------+--------------+ ]
| not-null | [ | size | data | ]
+----------+ [ +------+--------------+ ]
| byte | [ | int | size octects | ]
+----------+ [ +------+--------------+ ]
[=========================]
欄位|描述 —|— not-null|如果位元組陣列不為 null,則為 1,如果為 null,則為 0 大小|位元組陣列中的位元組數 資料|位元組陣列的資料
N 大小的位元組陣列類型編碼
固定大小的位元組陣列欄位不可以為 null,並且其長度必須為 N 長度。用於始終為固定大小的位元組陣列。
N 大小的位元組陣列編碼
+-----------+
| data |
+-----------+
| N octects |
+-----------+
欄位|描述 —|— 資料|位元組陣列的資料
Throwable 類型編碼
Throwable 欄位可以為 null。如果為 null,則編碼為單個「0」位元組。
throwable 編碼
[=If not-null is 1===========================================================================]
[ [=If StackTraceEnabled option is enabled.==================] ]
[ [ [=Repeated size times======================] ] ]
+----------+ [ +----------------+---------+ [ +-------+ [ +--------+--------+--------+-------------+ ] ] ]
| not-null | [ | exception-name | message | [ | size | [ | class | method | file | line-number | ] ] ]
+----------+ [ +----------------+---------+ [ +-------+ [ +--------+--------+--------+-------------+ ] ] ]
| byte | [ | string | string | [ | short | [ | string | string | string | int | ] ] ]
+----------+ [ +----------------+---------+ [ +-------+ [ +--------+--------+--------+-------------+ ] ] ]
[ [ [============================================] ] ]
[ [==========================================================] ]
[============================================================================================]
欄位 | 描述 |
---|---|
非 null | 如果 Throwable 不為 null,則為 1,如果 Throwable 為 null,則為 0 |
例外名稱 | 例外的類別名稱 |
訊息 | 例外訊息 |
大小 | 堆疊追蹤中的堆疊框架數 |
類別 | 堆疊框架中類別的名稱 |
方法 | 堆疊框架中方法的名稱 |
檔案 | 堆疊框架中檔案的名稱 |
行號 | 堆疊框架中的行號 |
如果在交換 WIREFORMAT_INFO 資料包後啟用了 StackTraceEnabled 編碼選項,則每個 Throwable 欄位都會附加堆疊追蹤資料。
巢狀命令類型編碼
巢狀命令欄位可以為 null。如果為 null,則編碼為單個「0」位元組。
巢狀物件編碼
[=If not-null is 1===================]
+----------+ [ +------+-------------------------+ ]
| not-null | [ | type | command-specific-fields | ]
+----------+ [ +------+-------------------------+ ]
| byte | [ | byte | variable sized | ]
+----------+ [ +------+-------------------------+ ]
[====================================]
欄位 | 描述 |
---|---|
非 null | 如果 Throwable 不為 null,則為 1,如果 Throwable 為 null,則為 0 |
類型 | 命令類型識別碼 |
命令特定欄位 | 命令的資料。其編碼取決於使用的類型 |
快取的巢狀命令類型編碼
可以快取巢狀命令類型,以便後續相同物件的封送操作會產生較小的線路大小。預設情況下,未啟用 CacheEnabled 選項,因此使用標準的巢狀物件編碼。
快取物件編碼
[=If CacheEnabled option is enabled=====================]
[ [=If new-value is 1===========] ]
[ +-----------+-------+ [ +-------------------------+ ] ]
[ | new-value | key | [ | command-specific-fields | ] ]
[ +-----------+-------+ [ +-------------------------+ ] ]
[ | byte | short | [ | nested-object | ] ]
[ +-----------+-------+ [ +-------------------------+ ] ]
[ [=============================] ]
[=====================================================] ]
[=If CacheEnabled option is disabled =]
[ +-------------------------+ ]
[ | command-specific-fields | ]
[ +-------------------------+ ]
[ | nested-object | ]
[ +-------------------------+ ]
[=====================================]
欄位 | 描述 |
---|---|
新值 | 如果值不在快取中,則為 1,如果已在快取中,則為 0 |
金鑰 | 用於識別快取中值的金鑰 |
命令特定欄位 | 命令的資料。其編碼取決於使用的類型 |
鬆散編碼
到目前為止解釋的預設編碼稱為「鬆散編碼」,是 OpenWire 首次初始化時使用的預設編碼。鬆散編碼易於實作,不會對封送/取消封送過程增加太多 CPU 負擔。它能夠在物件樹的單次傳遞中封送物件圖形。
緊湊編碼
OpenWire 支援另一種編碼選項,稱為緊湊編碼。使用緊湊編碼時,它會使用位元流將所有布林值封送到位元流中的位元,而在鬆散編碼中,這些布林值會佔用一個位元組。為了建置位元流,需要進行物件圖的 2 次傳遞,因此這是一個 CPU 密集度更高的封送過程,但它會產生較小的線路大小。