協議框架
CoAP默認運行在UDP上,但它也支持運行在SMS,TCP等數據傳輸層上。本文主要是基於UDP上的CoAP協議介紹
1.消息模型 Messages
COAP協議通信是通過在UDP上傳輸消息類完成。UDP比作公路話,消息就是公路上汽車。
COAP定義了4種類型消息,來實現設備端與雲端之間雙向通信
1. 需要確認消息 CON
2. 不需要確認消息 NON (適用於消息會重復頻繁的發送,丟掉消息不對業務產生影響)
3. 確認應答消息 ACK
4. 復位消息 RST
基於4種消息類型,可以實現2種傳輸質量。即可靠消息傳輸 與 不可靠消息傳輸。
怎么是可靠消息傳輸?
主要是通過確認及重傳機制來實現的,客戶端發送消息后,需要等待服務器收到通知, 如果在規定時間內,沒有收到需要重新發送數據。 可靠傳輸是基於CON消息傳輸的,服務器端收到CON類型的消息后,需要返回ACK消息,客戶端到在指定時間ACK_TIMEOUT內收到ACK消息后,才代表這個消息以可靠到服務器端。
怎么是不可靠消息傳輸?
客戶端只管發送消息, 不管服務器端有沒有收到,因此可能存在丟包。不可靠傳輸是基於NON消息傳輸的。服務器端收到NON類型的消息后,不用回復ACK消息。
2.資源請求/響應模型 Requests/Responses
對於物聯網,服務器上的資源可以簡單的認為是物聯網設備的實時運行影子, 通過訪問服務器上資源就可以實現與設備間數據的交互。 上面談到的消息模型比如汽車話, 資源請求及響應好比汽車上貨物。 資源請求及響應內容最終會被放在CoAP消息包里面。CoAP請求與響應,類似HTTP,且根據RESTful架構設計的。 CoAP客戶端發出請求,CoAP服務端進行請求處理然后發送響應。
COAP 請求Request方法: 請求方法與HTTP協議類似,有4個。 GET, PUT, POST, DELETE, 所有的請求方法都會放在CoAP CON/NON消息里面進行傳輸。
COAP 請求響應Response代碼: 響應內容也與HTTP協議類似。 主要有如下3類:
- Success 2.xx 代表客戶端請求被成功接收並被成功處理
- Client Error 4.xx 代表客戶端請求有錯誤,比如參數錯誤等
- Server Error 5.xx 代表服務器在執行客戶端請求時出錯。
所有的請求服務器響應可以放在CoAP CON/NON/ACK消息里面進行傳輸。針對CoAP 帶CON消息請求,響應如果快速處理完(有些請求的處理需要耗時多,服務器無法立即響應),則可直接放在ACK消息包里面返回。對於無法立即響應的,服務器帶資源ready后,會單獨發一個響應消息包給客戶端
服務器上可訪問資源統一用URL來定位(比如/deviceID/temp 訪問某個設備的溫度信息)。客戶端通過某個資源的URL來訪問服務器具體資源,通過4個請求方法(GET,PUT,POST,DELETE)完成對服務器上資源增刪改查操作。
舉個例子: 比如某個設備需要從服務器端查詢當前溫度信息。
- 請求消息(CON): GET /temperature , 請求內容會被包在CON消息里面
- 響應消息 (ACK): 2.05 Content "22.5 C" ,響應內容會被放在ACK消息里面
3.消息報文定義 Messages Define
Header(必須):固定4個byte
- Ver : 2bit, 代表版本信息,當前是1
- T: 2bit, 代表該消息類型, CON, NON. ACK, RST
- TKL: 4bit,token長度, 當前支持0~8B長度,其他長度保留將來擴展用
- Code:8bit,分成前3bit(07)和后5bit(031),前3bit代表類型。 0代表空消息或者請求碼, 2開頭代表響應碼,取值如下:
0.00 Indicates an Empty message 0.01-0.31 Indicates a request. 1.00-1.31 Reserved 2.00-5.31 Indicates a response. 6.00-7.31 Reserved
- Message ID:16bit, 代表消息MID,每個消息都有一個ID ,重發的消息MID不變。
token(可選)
也叫做請求ID。把響應與之前的請求關聯起來。有時候客戶端發送出請求帶上token,服務器端有時不能立即響應, 當服務器端准備好數據后,會單獨發送一個消息給客戶端, 這時候客戶端需要判斷這個消息是針對之前的哪個請求回復的,token用途就在這里,通過token,客戶端收到響應后,取出TOKEN,就可以知道該響應是針對之前哪個請求回復的。
option(可選,0個或者多個)
請求消息 與回應消息都可以0~多個options。 主要用於描述請求或者響應對應的各個屬性,類似參數或者特征描述。
payload(可選)
實際攜帶數據內容, 若有, 前面加payload 標志 OxFF.
option 介紹
格式
當一個消息報文里面有多個option時,每個option需要按照該option在協議里面對應的編號順序排列下來。並且每個option索引是通過增量來計算的。option Delta 代表相對於前面一個option編號的增量。
舉個例子
假設前面一個option編號為20, 當前option編號為25,則當前option的增量Delta就設置為5
增量最大可占用2個byte, 計算方式如下
當option Delta = 0~12時,只占4bit。
當option Delta =13 則占1B, 實際數字是option Delta【extended】 - 13
當option Delta =14 則占2B , 實際數字是option Delta【extended】 - 269
COAP 支持OPTION編號列表, 是HTTP協議 options 子集。
舉例 Uri-Host:服務器主機名稱,如californium.eclipse.org
Uri-Port:服務器端口號,默認為5683
Uri-Path:資源路路徑,如\temperature
Uri-Query:訪問資源參數,例如?v=1&t=2
4.塊傳輸
需要傳輸大量數據時,比如一個大文件,需要采用分塊傳輸,把文件拆解成多個塊進行傳輸。擴展的塊傳輸協議在COAP基礎協議上增加了3個options, 2個response codes 用於塊傳輸大小協商及控制。
block option結構
有三部分組成:
SZX: Block Size,占用2bit,取值范圍0~6,對應每個block 大小為2xx(SZX+4),即范圍(16 ~ 1024),以Byte為單位
M: More Flag,占用1bit, 代表是否還有剩下數據塊未傳輸。如果設置為0,代表數據塊都已傳輸出去
NUM: Block Number, 占用0~3Byte,代表當前塊編號,以0開始, 如我們要傳10個數據塊,則數據塊的編號為0~9
option block1: 主要用於客戶端發出請求時,分塊傳輸,比如需要上傳一個大的數據包到服務器上。
option block2: 主要用於服務器端響應時,分塊傳輸, 比如設備端發起資源發現式,由於服務器上資源較多,就要啟動分塊傳輸。
Size option
主要用於向對方說明,這次塊傳輸需要傳送的數據總數量。
Size1 option: 代表客戶度發出請求里面資源總的大小。
Size2 option: 代表服務器端響應資源總的大小。
如何啟動塊傳輸?
當請求消息或者響應消息里面有出息 block1/block2 option時,代表這是塊傳輸通信。需要根據option block 里面M標識,決定是否繼續進行塊傳輸。
示例
第一個消息,客戶端發起發現資源請求信息CON並設置Block2:0(NUM)/0(M)/64(SZX)告訴服務器端,能接受最大block size為64.
第二個消息。服務器端回復確認消息ACK,並設置Block2:0/1/64,告訴客戶端,block size已接受為64, 且后面還有數據,當前傳輸塊編號是0. size2:1094, 告訴客戶端,接下來總的數據大小是1094B。
第三個消息,客戶端發起請求獲取下一個block。設置Block2:1/0/64.告訴服務器端下一個要獲取的block編號是1.
5.訂閱與發布
MQTT協議是基於訂閱與發布模型的,coap通過擴展協議方式也簡單的實現了訂閱與發布模型。
當一個客戶端需要定期去查詢服務器端某個資源的最新狀態時,訂閱與發布模型就非常有用,不用這個模型,客戶端就要周期的不斷發送請求到服務器端。
模型框架
關鍵概念 主題Subject: 代表CoAP服務器上的某個資源resource,該資源狀態隨時可能發生變化 觀察者Observer:代表對某個coap資源最新狀態感興趣的客戶端CoAP Client 登記Registration: 觀察者需要向服務器CoAP server登記感興趣的主題Subject。
通知Notification:當CoAP觀察到某個主題發生狀態變化時,CoAP服務器會主動向該主題下的已登記的觀察者列表里面的每個觀察者發送其訂閱的主題最新狀態數據。 備注:如果已訂閱某個主題的CoAP client對CoAP server Notification無法確認,則會從主題訂閱列表里面移除掉。
訂閱與發布協議在COAP基礎協議上增加了1個Observe option, 其值為整數,通過該options來實現訂閱與發布模型管理
在get請求消息里面
oberser value 為 0: 代表向CoAP服務器端訂閱一個主題。
oberser value 為 1: 代表向CoAP服務器端移除一個已訂閱主題。
在notification消息里面
oberser value 代表 主題發生變化時,檢測到順序,以便客戶端可以知道狀態變化的先后。
舉個例子
\1. 客戶端向服務器端登記感興趣的主題 /temperature
\2. 當temperature發生狀態改變時,服務器端主動通知到客戶端。
\3. 客戶端根據token,就可以與之前訂閱主題關聯起來,以此確定是哪個主題訂閱的。
一個CoAP Client可以分次向CoAP server訂閱多個資源主題。 一個CoAP server上的主題可以被多個觀察者(CoAP Client)訂閱。 這樣就通過了CoAP server實現了CoAP Client之間直接數據轉發通信。
可以通過靈活設計服務器上的資源鏈接,來實現對某個主題的條件訂閱(類似觸發器或者閥值等)。 比如訂閱主題是: coap://server/temperature/critical?above=42, 當溫度超過42,CoAP Server需要發送通知。