HarmonyOS IPC Kit進階:客戶端與服務端的基礎通訊

SameX發表於2024-11-01

本文旨在深入探討華為鴻蒙HarmonyOS Next系統(截止目前API12)的技術細節,基於實際開發實踐進行總結。主要作為技術分享與交流載體,難免錯漏,歡迎各位同仁提出寶貴意見和問題,以便共同進步。本文為原創內容,任何形式的轉載必須註明出處及原作者。

本文將深入探討如何使用 IPC Kit 實現客戶端 (Client) 與服務端 (Server) 之間的基礎通訊,並解析 Proxy 和 Stub 在通訊過程中的角色。

客戶端與服務端通訊流程

  1. 服務端註冊能力:Server 端首先需要將自身能力 (System Ability) 註冊到系統能力管理者 (SAMgr) 中。
  2. 客戶端獲取 Proxy:Client 端從 SAMgr 獲取對應能力的 Proxy 物件。
  3. 客戶端傳送請求:Client 端透過 Proxy 物件向 Server 端傳送請求。
  4. 服務端處理請求:Server 端的 Stub 物件接收並處理 Client 端的請求。
  5. 服務端返回結果:Server 端將處理結果返回給 Client 端。
  6. 客戶端接收結果:Client 端接收 Server 端返回的結果。

Proxy 和 Stub 的角色

  • Proxy:Client 端的代理物件,用於轉發 Client 的請求到 Server 端。Proxy 物件具有與 Server 端相同的方法介面,Client 端透過呼叫 Proxy 物件的方法來傳送請求。
  • Stub:Server 端的代理物件,用於接收 Client 端的請求並呼叫 Server 的方法。Stub 物件實現了 Server 端的方法介面,並負責處理 Client 端的請求。

IPC Client 代理與服務端 Stub 的實現

  1. 服務端
  • 建立 OHIPCRemoteStub 物件。
  • 實現服務端的方法,並在 OnRemoteRequest 回撥函式中處理 Client 端的請求。
  • 將服務註冊到 SAMgr。
  1. 客戶端
  • 獲取對應能力的 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 實現高效的程序間通訊。

相關文章