CoAP Observe實作Subscription(訂閱)機制

邱奕修
Jul 31, 2021

--

RFC7641 — Observing Resources in the Constrained Application Protocol (CoAP)

Constrained Application Protocol (CoAP) 在2015年提出延伸規格書讓CoAP client能”observe” resources (rfc7641)。本文用node-coap搭配node-coap-client完成簡單Subscription範例(包含unsubscribe功能)

範例原型:

node-coap範例中有提供observe_client.jsobserve_server.js的範例。

client端部分,在request中observe的部分設定為true,即可發送CoAP observe message,允許與server建立串流(stream)並透過更新串流來實現subscribe的功能。

server端部分,透過setInterval每秒觸發event並以res.write將現在時間寫入與client端建立之串流,完成publish訊息的功能。並透過finish event來clearInterval,但範例中並未展示如何觸發finish event。

然而在我測試的過程中發現,finish event的觸發條件相當奇怪,需要在server端中執行res.close()才能觸發finish event,在client端中執行是沒有反應的,且在node-coap issue#83 中可以看出node-coap並沒有在client端中可以觸發finish event的API 。這使得client想要實現unsubscribe功能是有困難的。

client端unsubscribe功能:

在rfc7641的3.6章節中可以看出,規格書並沒有強制開發人員提供unsubscribe(deregister)功能。這樣的規劃使得node-coap中並沒有設計比較直接unsubscribe的方法(ex. unsubscribe API),而是要透過CoAP底層的方式來觸發。在node-coap issue#152 中可以找到client端unsubscribe的兩種辦法:

  1. send observe request with observe option value 1 (same token)
  2. send a CoAP RESET message

然而無論1或2在node-coap上都是不易實現的。1的部分,在我目前測試下來的結果是,單使用node-coap沒有辦法設定新的request的token為原先request的token。2的部分,在node-coap issue#154中可以看到在observe message情況下,發送RESET message是有問題的

以node-coap-client套件實現unsubscribe功能:

就在我以為窮途末路了的情況下,我嘗試了node-coap-client這個比較小眾的套件,該套件提供stopObserving功能,且經過測試後,是能成功停止接收訊息,並觸發server端finish event的。

稍微追蹤了一下原始碼與運用我薄弱的程式能力進行推導後,發現stopObserving內部是call了forgetRequest,而forgetRequest主要功能似乎是透過clear TTL來中止client端的retransmission,以此達到unsubscribe的功能。

stopObserving原始碼

心得:

在這次經驗中,我了解到我對於CoAP底層的內容還是沒有很熟悉,遠遠不及那些在node-coap中回覆issue的大神們(廢話)。但這樣沉浸在規格書與issue中的經驗還是很難能可貴,所以還是紀錄/分享一下。如果分享內容中有任何錯誤再麻煩提出指正了。

然後,小小小抱怨一下,node-coap的文件真的是偏爛,API寫得不太清楚,範例又都很簡單,常常需要自己摸索嘗試一些很基本的東西…

非常感謝讀完本篇文章,希望本文能對你有些幫助,記得按拍手給我一些鼓勵,Medium 文章中一個人最多能按 50 下 !

--

--

邱奕修
邱奕修

No responses yet