本文旨在深入探讨华为鸿蒙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 实现高效的进程间通信。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。