本文旨在深入探討華為鴻蒙HarmonyOS Next系統(截止目前API12)的技術細節,基於實際開發實踐進行總結。主要作為技術分享與交流載體,難免錯漏,歡迎各位同仁提出寶貴意見和問題,以便共同進步。本文為原創內容,任何形式的轉載必須註明出處及原作者。
本文將深入探討如何使用 IPC Kit 實現客戶端 (Client) 與服務端 (Server) 之間的基礎通訊,並解析 Proxy 和 Stub 在通訊過程中的角色。
客戶端與服務端通訊流程
- 服務端註冊能力:Server 端首先需要將自身能力 (System Ability) 註冊到系統能力管理者 (SAMgr) 中。
- 客戶端獲取 Proxy:Client 端從 SAMgr 獲取對應能力的 Proxy 物件。
- 客戶端傳送請求:Client 端透過 Proxy 物件向 Server 端傳送請求。
- 服務端處理請求:Server 端的 Stub 物件接收並處理 Client 端的請求。
- 服務端返回結果:Server 端將處理結果返回給 Client 端。
- 客戶端接收結果:Client 端接收 Server 端返回的結果。
Proxy 和 Stub 的角色
- Proxy:Client 端的代理物件,用於轉發 Client 的請求到 Server 端。Proxy 物件具有與 Server 端相同的方法介面,Client 端透過呼叫 Proxy 物件的方法來傳送請求。
- Stub:Server 端的代理物件,用於接收 Client 端的請求並呼叫 Server 的方法。Stub 物件實現了 Server 端的方法介面,並負責處理 Client 端的請求。
IPC Client 代理與服務端 Stub 的實現
- 服務端:
- 建立
OHIPCRemoteStub
物件。 - 實現服務端的方法,並在
OnRemoteRequest
回撥函式中處理 Client 端的請求。 - 將服務註冊到 SAMgr。
- 客戶端:
- 獲取對應能力的 Proxy 物件。
- 透過 Proxy 物件傳送請求。
- 接收 Server 端返回的結果。
使用 IPC Kit 建立遠端 Proxy 和 Stub
// 服務端
OHIPCRemoteStub *stub = OH_IPCRemoteStub_Create("com.example.service", &MyService::OnRemoteRequest, nullptr, this);
OH_IPCRemoteStub_RegisterSystemAbility(stub, MY_SERVICE_ID);
// 客戶端
OHIPCRemoteProxy *proxy = OH_IPCRemoteProxy_Create(MY_SERVICE_ID, "com.example.service");
非同步通訊模式的實現
IPC Kit 支援非同步通訊模式,Client 端可以傳送請求並立即返回,無需等待 Server 端處理完成。Server 端處理完成後,會透過回撥函式將結果返回給 Client 端。
// 客戶端
OH_IPC_MessageOption option = { OH_IPC_REQUEST_MODE_ASYNC, 0 };
OH_IPCRemoteProxy_SendRequest(proxy, MY_METHOD_ID, data, nullptr, &option);
// 服務端
int MyService::OnRemoteRequest(uint32_t code, const OHIPCParcel *data, OHIPCParcel *reply, void *userData) {
// 處理請求
// ...
// 返回結果
OH_IPCRemoteProxy_SendRequest(proxy, MY_METHOD_ID, data, reply, &option);
}
程式碼示例:IPC Client 與服務端的基礎通訊程式碼
// 服務端
class MyService : public OHIPCRemoteStub {
public:
MyService() : OHIPCRemoteStub("com.example.service", &MyService::OnRemoteRequest) {}
~MyService() override {
OH_IPCRemoteStub_Destroy(this);
}
int Add(int a, int b, int *result) {
*result = a + b;
return OH_IPC_SUCCESS;
}
static int OnRemoteRequest(uint32_t code, const OHIPCParcel *data, OHIPCParcel *reply, void *userData) {
MyService *service = reinterpret_cast<MyService *>(userData);
if (service == nullptr) {
return OH_IPC_CHECK_PARAM_ERROR;
}
int a = 0, b = 0;
OH_IPCParcel_ReadInt32(data, &a);
OH_IPCParcel_ReadInt32(data, &b);
int result = 0;
service->Add(a, b, &result);
OH_IPCParcel_WriteInt32(reply, result);
return OH_IPC_SUCCESS;
}
private:
int MY_METHOD_ID = 1;
};
// 客戶端
OHIPCRemoteProxy *proxy = OH_IPCRemoteProxy_Create(MY_SERVICE_ID, "com.example.service");
OH_IPC_MessageOption option = { OH_IPC_REQUEST_MODE_SYNC, 0 };
OH_IPCParcel data, reply;
OH_IPCParcel_WriteInt32(&data, 1);
OH_IPCParcel_WriteInt32(&data, 2);
OH_IPCRemoteProxy_SendRequest(proxy, MY_METHOD_ID, &data, &reply, &option);
int result = 0;
OH_IPCParcel_ReadInt32(&reply, &result);
printf("Result: %d\n", result);
總結
本文詳細介紹瞭如何使用 IPC Kit 實現客戶端與服務端的基礎通訊,並解析了 Proxy 和 Stub 在通訊過程中的角色。透過理解這些概念和程式碼示例,我們可以輕鬆地構建自己的客戶端-服務端應用,並利用 IPC Kit 實現高效的程序間通訊。