DEV Community

SameX
SameX

Posted on

HarmonyOS IPC Kit进阶:客户端与服务端的基础通信

本文旨在深入探讨华为鸿蒙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 的角色
  7. Proxy:Client 端的代理对象,用于转发 Client 的请求到 Server 端。Proxy 对象具有与 Server 端相同的方法接口,Client 端通过调用 Proxy 对象的方法来发送请求。
  8. Stub:Server 端的代理对象,用于接收 Client 端的请求并调用 Server 的方法。Stub 对象实现了 Server 端的方法接口,并负责处理 Client 端的请求。 ### IPC Client 代理与服务端 Stub 的实现
  9. 服务端
  10. 创建 OHIPCRemoteStub 对象。
  11. 实现服务端的方法,并在 OnRemoteRequest 回调函数中处理 Client 端的请求。
  12. 将服务注册到 SAMgr。
  13. 客户端
  14. 获取对应能力的 Proxy 对象。
  15. 通过 Proxy 对象发送请求。
  16. 接收 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");
Enter fullscreen mode Exit fullscreen mode

异步通信模式的实现

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);
}
Enter fullscreen mode Exit fullscreen mode

代码示例: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);
Enter fullscreen mode Exit fullscreen mode

总结

本文详细介绍了如何使用 IPC Kit 实现客户端与服务端的基础通信,并解析了 Proxy 和 Stub 在通信过程中的角色。通过理解这些概念和代码示例,我们可以轻松地构建自己的客户端-服务端应用,并利用 IPC Kit 实现高效的进程间通信。

Top comments (0)