物聯網架構成長之路(61)-物聯網第三方應用命令下發方案


0.前言

  

  上一篇博客講的這個圖,說到,設備主動上報數據到應用服務器端,只說到基於MQ來實現,只講到安裝篇,至於代碼篇,等后面實際用到再繼續深入了解。本篇博客主要講,客戶端(手機或者PC端)命令下發到設備,然后設備應答,返回結果到客戶端。常用於掃碼支付類應用。這該是如何設計呢?以前有說到,把手機或者PC客戶端當作一個設備,同樣接入MQTT Broker,這樣,設備和客戶端,同時訂閱和發布相同Topic,就可以兩者之間進行通信。這種方式實現比較簡單。效率高。適用范圍比較單一。一般也就用於自家設備與自家手機應用客戶端。適合公司做自己項目的公司。因為這種方式,平台端還需要管理終端用戶,這對於互聯網公司來說,一般是不太樂意接受的。

  下面講到的這種異步調用與同步調用,比較適合一些硬件廠商,或者一些想做大平台的公司。就是提供API給第三方客戶接入。完全分離設備端廠商與應用端廠商,兩者只需要按照流程接入即可,不用管Topic的事情。這樣做的好處是,可以做成一個類似小米一樣的生態系統。定好協議,左邊是給設備廠商接入,右邊是給第三方公司,特別是互聯網公司接入。平台只做好設備認證和客戶應用接入。客戶的終端客戶我們平台端就不需要管了。專心做好平台,做好生態即可。

  應用場景:

  假如我是一個賣設備模塊的公司,假如這個模塊就一個開關功能。現在定義好模塊的通信協議。開放給硬件產品公司模塊,就一個功能,開跟關。至於硬件產品公司,把開關應用到消防安防的開關,還是閘門、門禁的開關,還是智能插座的開關等等開關類應用。然后這批模塊,按照不同的產品公司,在物聯網平台創建好模型,創建好產品。完成設備接入。

  下一步,就是開放API給第三方軟件公司。軟件公司,只需要與平台對接,通過產品key,設備sn,命令參數,就可以下發命令到設備。第三方軟件公司,開發自己的APP應用。接收命令后通過RPC調用物聯網平台,平台下發命令,設備應答,平台返回命令下發結果。完成整個調用。(以上應用場景,均可用於共享儀器,掃碼支付等場景)

 

1. 異步調用

  

2. 同步調用

  

  注:本時序圖,最后為什么會有輪詢呢?因為在一個同步調用過程中,會設置超時,如果超時時間內,設備還無法回復。那么就返回超時並返回請求的Msgid給應用服務器。應用服務根據MsgID再去定時輪詢。(也有可能是硬件故障無法回復)。

  當然上面的應用服務器與客戶端之間,除了Http請求外,可以采用其他的請求方式。

 

3. 同步調用參考代碼

  同步調用,是基於Java Servlet 3.x 提供的DeferredResult實現的。

  MessageQueueDeferredService.java

 1 package com.wunaozai.demo.deferred;
 2 
 3 import java.util.HashMap;
 4 import java.util.Map;
 5 
 6 import org.springframework.stereotype.Service;
 7 import org.springframework.web.context.request.async.DeferredResult;
 8 
 9 @Service
10 public class MessageQueueDeferredService {
11 
12     /**
13      * 內存級別消息隊列
14      */
15     private final Map<String, DeferredResult<String>> results =
16             new HashMap<String, DeferredResult<String>>();
17     
18     /**
19      * 設置應答
20      * @param key
21      * @param value
22      * @return
23      */
24     public boolean setResponse(String key, String value) {
25         if(results.containsKey(key)) {
26             DeferredResult<String> res = results.get(key);
27             res.setResult(value);
28             results.remove(key);
29             return true;
30         }
31         //可能超時或者不存在對應key
32         return false;
33     }
34     /**
35      * 設置請求
36      * @param key
37      * @param result
38      * @return
39      */
40     public DeferredResult<String> setRequest(String key) {
41         DeferredResult<String> result = new DeferredResult<String>(5000L, "not response");
42         results.put(key, result);
43         result.onTimeout(new Runnable() {
44             @Override
45             public void run() {
46                 results.remove(key, result);
47             }
48         });
49         result.onCompletion(new Runnable() {
50             @Override
51             public void run() {
52                 results.remove(key, result);
53             }
54         });
55         return result;
56     }
57 
58 }

  DeferredResultController.java

 1 package com.wunaozai.demo.deferred;
 2 
 3 import org.springframework.beans.factory.annotation.Autowired;
 4 import org.springframework.web.bind.annotation.GetMapping;
 5 import org.springframework.web.bind.annotation.RequestMapping;
 6 import org.springframework.web.bind.annotation.RestController;
 7 import org.springframework.web.context.request.async.DeferredResult;
 8 
 9 @RestController
10 @RequestMapping(value="/deferredresult/")
11 public class DeferredResultController {
12 
13     @Autowired
14     private MessageQueueDeferredService messagequeuedeferredService;
15     
16     @GetMapping(value="/request")
17     public DeferredResult<String> setRequest(String msgid){
18         DeferredResult<String> result = messagequeuedeferredService.setRequest(msgid);
19         return result;
20     }
21     @GetMapping(value="/response")
22     public boolean setResponse(String msgid, String value) {
23         boolean flag = messagequeuedeferredService.setResponse(msgid, value);
24         return flag;
25     }
26 
27 }

  運行結果

  

  前三次請求,由於沒有調用response方法,所以等到5秒超時。並返回not response。等第四次,在5秒內訪問 http://127.0.0.1:8080/deferredresult/reponse?msgid=001&value=test ,然后就在 http://127.0.0.1:8080/deferredresult/request?msgid=003 頁面看到返回結果test了。

 

參考資料:

  https://www.cnblogs.com/coderxiaohei/p/14061468.html

 

本文地址:https://www.cnblogs.com/wunaozai/p/14078660.html
本系列目錄: https://www.cnblogs.com/wunaozai/p/8067577.html
個人主頁:https://www.wunaozai.com/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM