整体架构理解
tips:图片太大,如果图表看不清提供了高清图源
一、架构总览
分布式软总线在 standard 系统上采用 OHOS 标准的 IPC Binder 机制 实现 Client-Server 架构。整体结构如下:

二、Server 端详解
2.1 SA 注册与启动
SA Profile: 4700.json
{
"process": "softbus_server",
"systemability": [{
"name": 4700,
"libpath": "libsoftbus_server.z.so",
"run-on-create": true,
"distributed": false,
"dump_level": 1
}]
}
- SA ID 为 4700,进程名为
softbus_server run-on-create: true表示 SystemAbilityManager 自动拉起- 由 init 配置 softbus_server.rc 在
post-fs-data阶段启动
2.2 类继承体系(Server 端)

2.3 SoftBusServer — 业务实现层
关键点:
- 双重继承:
class SoftBusServer : public SystemAbility, public SoftBusServerStub OnStart()中调用InitSoftBusServer()初始化所有核心模块- 每个接口方法的实现都是直接转发到 core/ 层的 C 函数:
// 传输 → TransCreateSessionServer()
int32_t SoftBusServer::CreateSessionServer(const char *pkgName, const char *sessionName) {
pid_t callingUid = OHOS::IPCSkeleton::GetCallingUid();
pid_t callingPid = OHOS::IPCSkeleton::GetCallingPid();
return TransCreateSessionServer(pkgName, sessionName, (int32_t)callingUid, (int32_t)callingPid);
}
// 组网 → LnnIpcServerJoin()
int32_t SoftBusServer::JoinLNN(const char *pkgName, void *addr, uint32_t addrTypeLen, bool isForceJoin) {
pid_t callingPid = OHOS::IPCSkeleton::GetCallingPid();
return LnnIpcServerJoin(pkgName, (int32_t)callingPid, addr, addrTypeLen, isForceJoin);
}
通过 IPCSkeleton::GetCallingUid/Pid() 获取调用方身份用于权限校验。
2.4 SoftBusServerStub — IPC 请求分发与权限
核心机制是 函数映射表:
// 构造函数中注册所有 IPC code → 处理函数 的映射
void SoftBusServerStub::InitMemberFuncMap() {
memberFuncMap_[MANAGE_REGISTER_SERVICE] = &SoftBusServerStub::SoftbusRegisterServiceInner;
memberFuncMap_[SERVER_CREATE_SESSION_SERVER] = &SoftBusServerStub::CreateSessionServerInner;
memberFuncMap_[SERVER_OPEN_SESSION] = &SoftBusServerStub::OpenSessionInner;
memberFuncMap_[SERVER_JOIN_LNN] = &SoftBusServerStub::JoinLNNInner;
memberFuncMap_[SERVER_PUBLISH_LNN] = &SoftBusServerStub::PublishLNNInner;
// ... 40+ 个接口
}
// IPC 请求入口
int32_t SoftBusServerStub::OnRemoteRequest(uint32_t code, MessageParcel &data,
MessageParcel &reply, MessageOption &option) {
// 1. 验证 InterfaceToken
// 2. 权限检查 (AccessToken + memberPermissionMap_)
// 3. 查 memberFuncMap_ 找到对应处理函数
// 4. 反序列化 data → 调用虚函数(由 SoftBusServer 实现)→ 序列化 reply
}
权限映射:
void SoftBusServerStub::InitMemberPermissionMap() {
// 传输相关接口需要 DISTRIBUTED_DATASYNC 权限
memberPermissionMap_[SERVER_CREATE_SESSION_SERVER] = OHOS_PERMISSION_DISTRIBUTED_DATASYNC;
memberPermissionMap_[SERVER_OPEN_SESSION] = OHOS_PERMISSION_DISTRIBUTED_DATASYNC;
// 组网相关接口需要 DISTRIBUTED_SOFTBUS_CENTER 权限
memberPermissionMap_[SERVER_JOIN_LNN] = OHOS_PERMISSION_DISTRIBUTED_SOFTBUS_CENTER;
memberPermissionMap_[SERVER_START_TIME_SYNC] = OHOS_PERMISSION_DISTRIBUTED_SOFTBUS_CENTER;
// SendMessage 无权限要求(通道已建立,消息发送本身不额外校验)
memberPermissionMap_[SERVER_SESSION_SENDMSG] = nullptr;
}
2.5 SoftbusClientInfoManager — 客户端注册管理
Server 端维护一个 客户端信息表,记录所有已注册的客户端:
class SoftbusClientInfoManager {
// key: pkgName, value: (pid, (IRemoteObject, DeathRecipient))
std::unordered_multimap<std::string, ClientObjPair> clientObjectMap_;
// 添加客户端(注册时调用)
int32_t SoftbusAddService(const std::string &pkgName, const sptr<IRemoteObject> &object, ...);
// 移除客户端(死亡时调用)
int32_t SoftbusRemoveService(const sptr<IRemoteObject> &object, ...);
// 获取客户端 Proxy(Server→Client 推送时使用)
sptr<IRemoteObject> GetSoftbusClientProxy(const std::string &pkgName);
};
2.6 SoftBusDeathRecipient — 客户端死亡监听
softbus_server_death_recipient.h
当客户端进程异常死亡时,Binder 会触发 OnRemoteDied() 回调,Server 端执行清理:
- 从
SoftbusClientInfoManager移除该客户端 - 调用
ClientDeathCallback()清理该客户端关联的会话、通道等资源
2.7 服务端初始化流程
softbus_server_frame.c 中的 InitSoftBusServer():
InitSoftBusServer()
├─ SoftbusConfigInit() // 读取特性配置
├─ LnnInitMonitorInit() // 初始化监控
├─ ServerStubInit() // IPC Stub 初始化
├─ SoftBusTimerInit() // 定时器
├─ LooperInit() // 事件循环
├─ InitDdos() // DDOS 防护
├─ InitServicesAndModules() // ★ 核心模块初始化
│ ├─ ConnServerInit() // 连接模块
│ ├─ AuthInit() // 认证模块
│ ├─ DiscServerInit() // 发现模块
│ ├─ BusCenterServerInit() // 组网模块
│ ├─ TransServerInit() // 传输模块
│ ├─ DiscEventManagerInit() // 发现事件管理
│ ├─ WifiDirectManager::init()// WiFi Direct
│ ├─ ConnBleDirectInit() // BLE Direct
│ └─ HiDumper + SysEvt // DFX
└─ SoftBusBtInit() // 蓝牙初始化
三、Client 端详解
3.1 类继承体系(Client 端)
3.2 ISoftBusClient — Server→Client 推送接口
这是 Server 主动推送给 Client 的回调接口,与 ISoftBusServer 方向相反:
| 接口方法 | 触发场景 |
|---|---|
OnChannelOpened() |
通道打开成功 |
OnChannelOpenFailed() |
通道打开失败 |
OnChannelClosed() |
通道关闭 |
OnChannelMsgReceived() |
收到通道消息 |
OnChannelQosEvent() |
QoS 事件 |
OnChannelLinkDown() |
链路断开 |
OnJoinLNNResult() |
组网结果回调 |
OnLeaveLNNResult() |
退网结果回调 |
OnNodeOnlineStateChanged() |
节点上下线 |
OnNodeBasicInfoChanged() |
节点信息变化 |
OnTimeSyncResult() |
时间同步结果 |
OnPublishLNNResult() |
发布结果 |
OnRefreshLNNResult() |
发现结果 |
OnRefreshDeviceFound() |
发现设备 |
OnDataLevelChanged() |
数据级别变化 |
OnBleRangeDone() |
BLE 测距完成 |
3.3 SoftBusClientStub — 客户端侧 IPC Stub
与 Server Stub 结构对称,也是用 函数映射表 分发:
SoftBusClientStub::SoftBusClientStub() {
memberFuncMap_[CLIENT_ON_CHANNEL_OPENED] = &SoftBusClientStub::OnChannelOpenedInner;
memberFuncMap_[CLIENT_ON_CHANNEL_MSGRECEIVED] = &SoftBusClientStub::OnChannelMsgReceivedInner;
memberFuncMap_[CLIENT_ON_JOIN_RESULT] = &SoftBusClientStub::OnJoinLNNResultInner;
memberFuncMap_[CLIENT_ON_NODE_ONLINE_STATE_CHANGED] = &SoftBusClientStub::OnNodeOnlineStateChangedInner;
// ... 25+ 个回调
}
收到 Server 推送后,反序列化数据,调用 SDK 层的回调函数(如 TransOnChannelOpened()、TransOnChannelMsgReceived()),最终触发应用注册的回调。
3.4 SoftBusServerProxyFrame — 客户端侧 IPC Proxy
softbus_server_proxy_standard.h
这是 Client 向 Server 发起请求的代理,核心流程:
int32_t SoftBusServerProxyFrame::SoftbusRegisterService(const char *clientPkgName, ...) {
// 1. 获取 Server 端的 Remote 对象
sptr<IRemoteObject> remote = Remote();
// 2. 获取/创建 ClientStub(单例),作为 Server 回调的入口
sptr<IRemoteObject> clientStub = SoftBusServerProxyFrame::GetRemoteInstance();
// 3. 序列化请求
MessageParcel data;
data.WriteInterfaceToken(GetDescriptor());
data.WriteRemoteObject(clientStub); // ★ 把 ClientStub 传给 Server
data.WriteCString(clientPkgName);
// 4. 通过 Binder 发送 IPC 请求
MessageParcel reply;
MessageOption option;
int32_t err = remote->SendRequest(MANAGE_REGISTER_SERVICE, data, reply, option);
// 5. 读取返回值
return reply.ReadInt32(serverRet);
}
关键点:GetRemoteInstance() 使用双重检查锁创建 SoftBusClientStub 单例,注册时将其作为 IRemoteObject 传给 Server,这样 Server 就有了向 Client 推送的通道。
四、双向 IPC 通信模型
这是整个架构最核心的设计——双向 IPC:
① 请求方向(Client → Server):
- 应用调用公开 API → SDK 层 →
SoftBusServerProxyFrame序列化参数 → BinderSendRequest()→ Server 端SoftBusServerStub::OnRemoteRequest()反序列化 → 权限检查 → 调用SoftBusServer的虚函数实现 → 转发到 core/ 层 C 函数
② 推送方向(Server → Client):
- Server 端核心模块产生事件 → 通过
SoftbusClientInfoManager::GetSoftbusClientProxy()获取客户端 Proxy → 调用 Proxy 的SendRequest()→ Binder → Client 端SoftBusClientStub::OnRemoteRequest()反序列化 → 调用 SDK 回调 → 触发应用层回调
五、客户端注册流程(完整时序)
Mermid版本

流程图

关键流程说明(配合图表理解)
| 步骤 | 组件 | 关键动作 | 说明 |
|---|---|---|---|
| ① | 应用 → SDK | InitSoftBus(pkgName) |
应用初始化软总线,传入包名用于身份标识 |
| ② | SDK → SAM | 获取 SA Proxy (ID=4700) | 从 SystemAbilityManager 获取远程服务代理 |
| ③ | SDK 自处理 | 创建 SoftBusClientStub |
单例模式,用于接收服务端主动推送的消息 |
| ④ | SDK → Server | SendRequest(REGISTER) |
通过 Binder 发起注册请求,携带 stub 引用和包名 |
| ⑤ | ServerStub | OnRemoteRequest() |
解析 Binder 协议码,分发到 memberFuncMap_ |
| ⑥ | ServerStub | 权限检查 | 校验调用方是否拥有 ohos.permission.DISTRIBUTED_DATA 等权限 |
| ⑦ | SoftBusServer | SoftbusRegisterService() |
业务层处理注册逻辑 |
| ⑧ | SoftBusServer | 检查客户端是否已存在 | 防止重复注册,若已存在则更新信息 |
| ⑨ | SoftBusServer | 创建 DeathRecipient |
绑定死亡通知,客户端崩溃时服务端能感知并清理资源 |
| ⑩ | ClientInfoManager | SoftbusAddService() |
持久化存储 clientProxy、pkgName、pid/uid 映射关系 |
注册完成后:
- Server 端持有 Client 的
IRemoteObject(即SoftBusClientStub),可以随时向 Client 推送事件 - Client 端持有 Server 的
IRemoteObject(即 SA Proxy),可以随时向 Server 发起请求 - DeathRecipient 确保 Client 异常死亡时 Server 能感知并清理资源
六、IPC 接口码定义
所有 IPC 通信的 code 定义在 softbus_server_ipc_interface_code.h 中,分为两组:
Server 端接口码(Client → Server 请求):
| Code | 接口 | 功能域 |
|---|---|---|
MANAGE_REGISTER_SERVICE |
SoftbusRegisterService |
框架 |
SERVER_CREATE_SESSION_SERVER |
CreateSessionServer |
传输 |
SERVER_OPEN_SESSION |
OpenSession |
传输 |
SERVER_CLOSE_CHANNEL |
CloseChannel |
传输 |
SERVER_SESSION_SENDMSG |
SendMessage |
传输 |
SERVER_JOIN_LNN |
JoinLNN |
组网 |
SERVER_LEAVE_LNN |
LeaveLNN |
组网 |
SERVER_PUBLISH_LNN |
PublishLNN |
发现 |
SERVER_REFRESH_LNN |
RefreshLNN |
发现 |
| ... | ... | ... |
Client 端接口码(Server → Client 推送):
| Code | 接口 | 功能域 |
|---|---|---|
CLIENT_ON_CHANNEL_OPENED |
OnChannelOpened |
传输 |
CLIENT_ON_CHANNEL_MSGRECEIVED |
OnChannelMsgReceived |
传输 |
CLIENT_ON_JOIN_RESULT |
OnJoinLNNResult |
组网 |
CLIENT_ON_NODE_ONLINE_STATE_CHANGED |
OnNodeOnlineStateChanged |
组网 |
CLIENT_ON_REFRESH_DEVICE_FOUND |
OnRefreshDeviceFound |
发现 |
| ... | ... | ... |
七、关键设计总结
| 设计要点 | 说明 |
|---|---|
| 双向 IPC | Client→Server 请求 + Server→Client 推送,两条 Binder 通道 |
| SA 机制 | Server 以 SystemAbility (ID=4700) 运行在独立进程,系统自动拉起 |
| Stub-Proxy 分离 | Server Stub 做反序列化+权限;Client Stub 做反序列化+回调分发 |
| 函数映射表 | memberFuncMap_ 将 IPC code 映射到成员函数指针,避免巨大 switch-case |
| 权限双检 | AccessToken 框架检查 + memberPermissionMap_ 接口级权限映射 |
| DeathRecipient | 双向死亡监听,Client 死亡 → Server 清理;Server 死亡 → Client 重连 |
| 客户端管理 | SoftbusClientInfoManager 以 pkgName+pid 为键管理多客户端 |
| PID/UID 传递 | 通过 IPCSkeleton::GetCallingPid/Uid() 获取调用方身份 |
| 模块化初始化 | InitSoftBusServer() 按依赖顺序初始化 Conn→Auth→Disc→BusCenter→Trans |
更多推荐

所有评论(0)