本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
處理程序間通訊 (IPC) APIs
受管整合中樞上的外部元件可以使用其代理程式元件和程序間通訊 (IPC) 與受管整合中樞 SDK 通訊。中樞上的外部元件範例是管理本機常式的協助程式 (持續執行的背景程序)。在通訊期間,IPC 用戶端是發佈命令或其他請求並訂閱事件的外部元件。IPC 伺服器是受管整合中樞 SDK 中的代理程式元件。如需詳細資訊,請參閱設定 IPC 用戶端。
若要建置 IPC 用戶端,IotmiLocalControllerClient
會提供 IPC 用戶端程式庫。此程式庫提供用戶端 APIs用於與 Agent 中的 IPC 伺服器通訊,包括傳送命令請求、查詢裝置狀態、訂閱事件 (例如裝置狀態事件),以及處理事件型互動。
設定 IPC 用戶端
IotmiLocalControllerClient
程式庫是基本 IPC APIs的包裝函式,可簡化和簡化在應用程式中實作 IPC 的程序。下列各節說明其提供的 APIs。
注意
本主題專門針對做為 IPC 用戶端的外部元件,而非 IPC 伺服器的實作。
-
建立 IPC 用戶端
您必須先初始化 IPC 用戶端,才能用來處理請求。您可以在程式
IotmiLocalControllerClient
庫中使用建構函數,以訂閱者內容char *subscriberCtx
做為參數,並根據它建立 IPC 用戶端管理員。以下是建立 IPC 用戶端的範例:// Context for subscriber char subscriberCtx[] = "example_ctx"; // Instantiate the client IotmiLocalControllerClient lcc(subscriberCtx);
-
訂閱 事件
您可以將 IPC 用戶端訂閱至目標 IPC 伺服器的事件。當 IPC 伺服器發佈用戶端訂閱的事件時,用戶端會收到該事件。若要訂閱,請使用
registerSubscriber
函數並提供要訂閱的事件 IDs,以及自訂回呼。以下是
registerSubscriber
函數的定義及其範例用量:iotmi_statusCode_t registerSubscriber( std::vector<iotmiIpc_eventId_t> eventIds, SubscribeCallbackFunction cb);
// A basic example of customized subscribe callback, which prints the event ID, data, and length received void customizedSubscribeCallback(iotmiIpc_eventId_t event_id, uint32_t length, const uint8_t *data, void *ctx) { IOTMI_IPC_LOGI("Received subscribed event id: %d\n" "length: %d\n" "data: %s\n", event_id, length, data); } iotmi_statusCode_t status; status = lcc.registerSubscriber({IOTMI_IPC_EVENT_DEVICE_UPDATE_TO_RE}, customerProvidedSubscribeCallback);
status
會定義 來檢查操作 (例如訂閱或傳送請求) 是否成功。如果操作成功,傳回的狀態為IOTMI_STATUS_OK (= 0)
。注意
IPC 程式庫具有下列訂閱訂閱者和事件數量上限的服務配額:
-
每個程序的訂閱者數目上限:5
在 IPC 程式庫
IOTMI_IPC_MAX_SUBSCRIBER
中定義為 。 -
定義的事件數目上限:32
在 IPC 程式庫
IOTMI_IPC_EVENT_PUBLIC_END
中定義為 。 -
每個訂閱者都有一個 32 位元事件欄位,其中每個位元對應於定義的事件。
-
-
將 IPC 用戶端連線至伺服器
IotmiLocalControllerClient
程式庫中的連線函數會執行任務,例如初始化 IPC 用戶端、註冊訂閱者,以及訂閱registerSubscriber
函數中提供的事件。您可以在 IPC 用戶端上呼叫連線函數。status = lcc.connect();
在您傳送請求或進行其他操作
IOTMI_STATUS_OK
之前,請確認傳回的狀態為 。 -
傳送命令請求和裝置狀態查詢
Agent 中的 IPC 伺服器可以處理命令請求和裝置狀態請求。
-
命令請求
形成命令請求承載字串,然後呼叫
sendCommandRequest
函數進行傳送。例如:status = lcc.sendCommandRequest(payloadData, iotmiIpcMgr_commandRequestCb, nullptr);
/** * @brief method to send local control command * @param payloadString A pre-defined data format for local command request. * @param callback a callback function with typedef as PublishCallbackFunction * @param client_ctx client provided context * @return */ iotmi_statusCode_t sendCommandRequest(std::string payloadString, PublishCallbackFunction callback, void *client_ctx);
如需命令請求格式的詳細資訊,請參閱命令請求。
範例 回呼函數
IPC 伺服器會先傳送訊息確認
Command received, will send command response back
給 IPC 用戶端。收到此確認後,IPC 用戶端可以預期命令回應事件。void iotmiIpcMgr_commandRequestCb(iotmi_statusCode_t ret_status, void *ret_data, void *ret_client_ctx) { char* data = NULL; char *ctx = NULL; if (ret_status != IOTMI_STATUS_OK) return; if (ret_data == NULL) { IOTMI_IPC_LOGE("error, event data NULL"); return; } if (ret_client_ctx == NULL) { IOTMI_IPC_LOGE("error, event client ctx NULL"); return; } data = (char *)ret_data; ctx = (char *)ret_client_ctx; IOTMI_IPC_LOGI("response received: %s \n", data); }
-
裝置狀態請求
與
sendCommandRequest
函數類似,此sendDeviceStateQuery
函數也會接受承載字串、對應的回呼和用戶端內容。status = lcc.sendDeviceStateQuery(payloadData, iotmiIpcMgr_deviceStateQueryCb, nullptr);
-
IPC 介面定義和承載
本節著重於專門用於代理程式和外部元件之間通訊的 IPC 介面,並提供這兩個元件之間 IPC APIs 的範例實作。在下列範例中,外部元件會管理本機常式。
在 IoTManagedIntegrationsDevice-IPC
程式庫中,會定義下列命令和事件,以便在 代理程式和外部元件之間進行通訊。
typedef enum { // The async cmd used to send commands from the external component to Agent IOTMI_IPC_SVC_SEND_REQ_FROM_RE = 32, // The async cmd used to send device state query from the external component to Agent IOTMI_IPC_SVC_SEND_QUERY_FROM_RE = 33, // ... } iotmiIpcSvc_cmd_t;
typedef enum { // Event about device state update from Agent to the component IOTMI_IPC_EVENT_DEVICE_UPDATE_TO_RE = 3, // ... } iotmiIpc_eventId_t;
命令請求
命令請求格式
-
範例 命令請求
{ "payload": { "traceId": "LIGHT_DIMMING_UPDATE", "nodeId": "1", "managedThingId": <ManagedThingId of the device>, "endpoints": [{ "id": "1", "capabilities": [ { "id": "matter.LevelControl@1.4", "name": "Level Control", "version": "1.0", "actions":[ { "name": "UpdateState", "parameters": { "OnLevel": 5, "DefaultMoveRate": 30 } } ] } ] }] } }
命令回應格式
-
如果來自外部元件的命令請求有效,代理程式會將其傳送至 CDMB (通用資料模型橋接器)。包含命令執行時間和其他資訊的實際命令回應不會立即傳回外部元件,因為處理命令需要一些時間。此命令回應是來自 代理程式的即時回應 (例如確認)。回應會告知外部元件受管整合已接收到 命令,如果沒有有效的本機字符, 會處理或捨棄該命令。命令回應會以字串格式傳送。
std::string errorResponse = "No valid token for local command, cannot process."; *ret_buf_len = static_cast<uint32_t>(errorResponse.size()); *ret_buf = new uint8_t[*ret_buf_len]; std::memcpy(*ret_buf, errorResponse.data(), *ret_buf_len);
裝置狀態請求
外部元件會將裝置狀態請求傳送至 代理程式。請求會提供裝置的 managedThingId
,然後 代理程式會回覆該裝置的狀態。
裝置狀態請求格式
-
您的裝置狀態請求必須有已查詢裝置的
managedThingId
。{ "payload": { "managedThingId": "testManagedThingId" } }
裝置狀態回應格式
-
如果裝置狀態請求有效,代理程式會以字串格式傳回狀態。
範例 有效請求的裝置狀態回應
{ "payload": { "currentState": "exampleState" } }
如果裝置狀態請求無效 (例如,如果沒有有效的字符、無法處理承載,或另一個錯誤案例),代理程式會傳回回應。回應包含錯誤代碼和錯誤訊息。
範例 無效請求的裝置狀態回應
{ "payload": { "response":{ "code": 111, "message": "errorMessage" } } }
命令回應
範例 命令回應格式
{ "payload": { "traceId": "LIGHT_DIMMING_UPDATE", "commandReceivedAt": "1684911358.533", "commandExecutedAt": "1684911360.123", "managedThingId": <ManagedThingId of the device>, "nodeId": "1", "endpoints": [{ "id": "1", "capabilities": [ { "id": "matter.OnOff@1.4", "name": "On/Off", "version": "1.0", "actions":[ {} ] } ] }] } }
通知事件
範例 通知事件格式
{ "payload": { "hasState": "true" "nodeId": "1", "managedThingId": <ManagedThingId of the device>, "endpoints": [{ "id": "1", "capabilities": [ { "id": "matter.OnOff@1.4", "name": "On/Off", "version": "1.0", "properties":[ { "name": "OnOff", "value": true } ] } ] }] } }