雲端式雲對接SDK,通過橋接服務,可將裝置接入阿里雲物聯網平台,實現裝置與物聯網平台通訊。本文介紹如何配置云云對接SDK,實現裝置上下線和訊息上下行等基礎能力。
擷取SDK
物聯網平台提供了云云對接SDK的Demo,具體內容,請參見alibabacloud-iot-bridge-core-demo。
流程圖
使用云云對接SDK,橋接裝置與物聯網平台的整體流程圖如下。
部署開發環境
部署Java SDK開發環境,並添加云云對接SDK的專案Maven依賴。
<dependency>
<groupId>com.aliyun.openservices</groupId>
<artifactId>iot-as-bridge-sdk-core</artifactId>
<version>2.4.1</version>
</dependency>
初始化
初始化SDK
建立BridgeBootstrap對象執行個體,調用bootstrap方法,在該方法中,向云云對接SDK註冊一個DownlinkChannelHandler回調,用於接收物聯網平台下行訊息。
完成SDK初始化後,SDK會讀取橋接器裝置資訊,並向物聯網平台發起橋接器裝置上線請求等。
程式碼範例:
BridgeBootstrap bridgeBootstrap = new BridgeBootstrap();
bridgeBootstrap.bootstrap(new DownlinkChannelHandler() {
@Override
public boolean pushToDevice(Session session, String topic, byte[] payload) {
//接收物聯網平台下行訊息。
String content = new String(bytes);
log.info("Get DownLink message, session:{}, {}, {}", session, topic, content);
return true;
}
@Override
public boolean broadcast(String topic, byte[] payload) {
return false;
}
});
配置橋接器裝置資訊
預設使用設定檔方式:從Java工程預設資源檔路徑src/main/resources/下讀取設定檔application.conf,格式為HOCON(JSON超集)。
云云對接SDK使用typesafe.config解析設定檔。
配置方法:動態註冊橋接器裝置和指定橋接器裝置。
動態註冊橋接器裝置的配置,請參見動態建立橋接器裝置。指定橋接器裝置的配置如下。
參數
是否必需
說明
productKey
是
橋接器裝置所屬產品的ProductKey。
deviceName
是
橋接器裝置的DeviceName。
deviceSecret
是
橋接器裝置的DeviceSecret。
subDeviceConnectMode
否
橋接器掛載裝置模式:
大型橋接器:傳入3,單橋接器下最大支援掛載500,000個裝置。
小型橋接器:不傳入,單橋接器下最大支援掛載1,500個裝置。
大型橋接器、小型橋接器的掛載裝置下線策略不同,請參見裝置下線。
http2Endpoint
是
HTTP2網關服務地址。橋接器裝置和物聯網平台通過HTTP2協議建立長串連通道。
地址結構:
企業版執行個體:
https://${IotInstanceId}.http2.iothub.aliyuncs.com:443
。其中,變數${IotInstanceId}需替換成執行個體ID。
例如:某使用者的企業版執行個體的執行個體ID為iot-cn-g06kwb****,地址為
https://iot-cn-g06kwb****.http2.iothub.aliyuncs.com:443
。公用執行個體:新舊版公用執行個體的地址填寫格式不同。
新版公用執行個體:與企業版執行個體填寫格式一致。
舊版公用執行個體:
https://${productKey}.iot-as-http2.${RegionId}.aliyuncs.com:443
。其中,變數${productKey}需替換成您的橋接器裝置所屬產品的ProductKey。
變數${RegionId}需替換成您的服務所在地區代碼。RegionId的表達方法,請參見地區和可用性區域。
例如:某使用者的橋接器裝置的productKey為a1abcab****,地區為華東2(上海),地址為
https://a1abcab****.iot-as-http2.cn-shanghai.aliyuncs.com:443
。
執行個體的詳細說明,請參見執行個體概述。
authEndpoint
是
裝置認證服務地址。
地址結構:
企業版執行個體:
https://${IotInstanceId}.auth.iothub.aliyuncs.com/auth/bridge
。其中,變數${IotInstanceId}需替換成執行個體ID。
例如:某使用者的企業版執行個體的執行個體ID為iot-cn-g06kwb****,則地址為
https://iot-cn-g06kwb****.auth.iothub.aliyuncs.com/auth/bridge
。公用執行個體:新舊版公用執行個體的地址填寫格式不同。
新版公用執行個體:與企業版執行個體填寫格式一致。
舊版公用執行個體:
https://iot-auth.${RegionId}.aliyuncs.com/auth/bridge
。其中,變數${RegionId}需替換成您的服務所在地區代碼。RegionId的表達方法,請參見地區和可用性區域。
例如:地區為華東2(上海),則地址為
https://iot-auth.cn-shanghai.aliyuncs.com/auth/bridge
。
以企業版執行個體為例,指定小型橋接器裝置的配置代碼如下:
// 服務地址 http2Endpoint = "https://iot-2w****.http2.iothub.aliyuncs.com:443" authEndpoint = "https://iot-2w****.auth.iothub.aliyuncs.com/auth/bridge" // 橋接器裝置資訊 productKey = ${bridge-ProductKey-in-Iot-Plaform} deviceName = ${bridge-DeviceName-in-Iot-Plaform} deviceSecret = ${bridge-DeviceSecret-in-Iot-Plaform}
裝置認證並上線
配置裝置上線
云云對接SDK中的裝置上線介面設定如下。
/**
* 裝置認證。
* @param newSession 裝置Session資訊,下行回調的時候會將這個Session傳遞迴來。
* @param originalIdentity 裝置原始身份標識符。
* @return
*/
public boolean doOnline(Session newSession, String originalIdentity);
裝置上線時,需要傳Session
。下行訊息回調時,把Session
回調給橋接器Server,橋接器Server通過Session
中的originalIdentity欄位,判斷訊息的來源裝置。
此外,Session
中可選的channel欄位,資料類型是Object,可存放裝置的串連資訊。例如,基於Netty構建的橋接器Server,channel欄位可存放裝置長串連對應的channel對象,訊息下行時,可直接從Session
中擷取channel進行操作。
云云對接SDK不會對channel資料做任何處理。您可根據使用情境,在channel中存放任何裝置相關的資訊。
程式碼範例:
UplinkChannelHandler uplinkHandler = new UplinkChannelHandler();
//建立Session。
Object channel = new Object();
Session session = Session.newInstance(originalIdentity, channel);
//裝置上線。
boolean success = uplinkHandler.doOnline(session, originalIdentity);
if (success) {
//裝置上線成功,橋接器Server接受後續裝置通訊請求。
} else {
//裝置上線失敗,橋接器Server可以拒絕後續裝置通訊請求,如中斷連線。
}
配置裝置原始身份標識符和裝置認證資訊的映射關係
預設使用設定檔方式:一般從Java工程預設資源檔路徑src/main/resources/下讀取設定檔devices.conf,格式為HOCON(JSON超集)。
云云對接SDK使用typesafe.config解析設定檔。
檔案格式及內容如下。
${device-originalIdentity} {
productKey : ${device-ProductKey-in-Iot-Plaform}
deviceName : ${device-DeviceName-in-Iot-Platform}
deviceSecret : ${device-DeviceSecret-in-Iot-Platform}
}
參數 | 是否必需 | 說明 |
productKey | 是 | 裝置所屬產品的ProductKey。 |
deviceName | 是 | 裝置的DeviceName。 |
deviceSecret | 是 | 裝置的DeviceSecret。 |
裝置發送上行資料
云云對接SDK的裝置上報訊息介面設定如下。
/**
* 發送裝置上行訊息,同步調用介面。
* @param originalIdentity 裝置原始身份標識符。
* @param protocolMsg 待發送訊息,包含Topic、訊息體、QoS等資訊。
* @param timeout 逾時時間,單位秒。
* @return 逾時時間內是否發送成功。
*/
boolean doPublish(String originalIdentity, ProtocolMessage protocolMsg, int timeout);
/**
* 發送裝置上行訊息,非同步呼叫介面。
* @param originalIdentity 裝置原始身份標識符。
* @param protocolMsg 待發送訊息,包含Topic、訊息體、QoS等資訊。
* @return 調用後立即返回CompletableFuture,調用者可進一步處理該future。
*/
CompletableFuture<ProtocolMessage> doPublishAsync(String originalIdentity,
ProtocolMessage protocolMsg);
介面調用程式碼範例如下。
DeviceIdentity deviceIdentity = ConfigFactory.getDeviceConfigManager().getDeviceIdentity(originalIdentity);
ProtocolMessage protocolMessage = new ProtocolMessage();
protocolMessage.setPayload("Hello world".getBytes());
protocolMessage.setQos(0);
protocolMessage.setTopic(String.format("/%s/%s/update", deviceIdentity.getProductKey(), deviceIdentity.getDeviceName()));
//同步發送。
int timeoutSeconds = 3;
boolean success = upLinkHandler.doPublish(originalIdentity, protocolMessage, timeoutSeconds);
//非同步發送。
upLinkHandler.doPublishAsync(originalIdentity, protocolMessage);
橋接器Server推送下行資料給裝置
橋接器Server在調用bootstrap方法時,向云云對接SDK註冊了DownlinkChannelHandler。當有下行訊息時,云云對接SDK就會回調DownlinkChannelHandler的pushToDevice方法。
您可在pushToDevice中,配置橋接器Server處理下行訊息。
指定的裝置通過云云對接SDK,接入物聯網平台後,無需裝置訂閱Topic,即可收到對應訊息。
pushToDevice方法中不要做耗時邏輯,否則會阻塞下行訊息接收的線程。如果有耗時或IO邏輯,例如收到物聯網平台下行訊息後,通過網路長串連發給子裝置,請採用非同步處理。
程式碼範例如下。
private static ExecutorService executorService = new ThreadPoolExecutor(
Runtime.getRuntime().availableProcessors(),
Runtime.getRuntime().availableProcessors() * 2,
60, TimeUnit.SECONDS,
new LinkedBlockingQueue<>(1000),
new ThreadFactoryBuilder().setDaemon(true).setNameFormat("bridge-downlink-handle-%d").build(),
new ThreadPoolExecutor.AbortPolicy());
public static void main(String args[]) {
//預設使用application.conf和devices.conf。
BridgeBootstrap bridgeBootstrap = new BridgeBootstrap();
bridgeBootstrap.bootstrap(new DownlinkChannelHandler() {
@Override
public boolean pushToDevice(Session session, String topic, byte[] payload) {
//接收物聯網平台下行訊息。
executorService.submit(() -> handleDownLinkMessage(session, topic, payload));
return true;
}
@Override
public boolean broadcast(String s, byte[] bytes) {
return false;
}
});
}
private static void handleDownLinkMessage(Session session, String topic, byte[] payload) {
String content = new String(payload);
log.info("Get DownLink message, session:{}, topic:{}, content:{}", session, topic, content);
Object channel = session.getChannel();
String originalIdentity = session.getOriginalIdentity();
}
參數 | 說明 |
session | 裝置doOnline時,傳入session,可以用來區分下行訊息是發給哪個裝置的。 |
topic | 下行訊息的Topic。 |
payload | 下行訊息的訊息體資料,為二進位格式。 |
裝置下線
分為以下情況:
小型橋接器:橋接器Server與物聯網平台之間的串連斷開時,所有裝置會自動從物聯網平台離線。
大型橋接器:橋接器Server與物聯網平台之間的串連斷開時,裝置不會自動從物聯網平台離線。橋接器重連後,可通過裝置下線介面主動更新裝置的狀態。
子裝置的狀態表示子裝置接入網關的狀態,由網關上報到物聯網平台重新整理該狀態。如果網關不能正常上報子裝置的狀態資訊到物聯網平台,則展示的子裝置狀態不會重新整理。
例如:某子裝置通過網關接入到物聯網平台,子裝置狀態為線上,如果此時網關與物聯網平台中斷連線,則網關不能上報子裝置的狀態到物聯網平台,該子裝置的狀態會一直顯示線上。
小型橋接器和大型橋接器:橋接器Server與物聯網平台之間的串連未斷開時,橋接器可以主動向物聯網平台上報某個裝置下線的訊息。
橋接器Server上報裝置下線的介面定義如下:
/** * 向物聯網平台上報某個裝置下線。 * @param originalIdentity 裝置原始身份標識符。 * @return 是否成功上報。 */ boolean doOffline(String originalIdentity);
調用下線介面程式碼範例如下:
upLinkHandler.doOffline(originalIdentity);
橋接器主動斷連和重連
橋接器可通過BridgeBootstrap對象執行個體,調用介面disconnectBridge和reconnectBridge分別實現與物聯網平台串連主動斷開和重連。
reconnectBridge介面僅用於重連,不可用於首次建連。
程式碼範例:
//主動斷開與物聯網平台的串連
bridgeBootstrap.disconnectBridge();
Thread.sleep(1000);
//判斷與物聯網平台是否保持著串連
boolean isConnected = bridgeBootstrap.isBridgeConnected();
//重建立立與物聯網平台的串連
bridgeBootstrap.reconnectBridge();
Thread.sleep(1000);
isConnected = bridgeBootstrap.isBridgeConnected();