openHarmony软总线架构分析
基本类阐述
本次说明可能侧重在标准系统之上。
软总线依旧采用鸿蒙经典的proxy - stub 架构,接口类 ISoftBusServer,ISoftBusClient。一般来说,一些服务就一个接口类,为什么软总线会有两个呢?,我们再看看继承关系。
proxy -stub 可以参考 https://ost.51cto.com/posts/10765
和ISoftBusServer 相关的有

类似的 ISoftBusClient

从上面的图中可以看出,一个stub甚至对应几个proxy,看下代码,可以看到就是proxy就是解耦,更加的职责清晰。
我们通过观察目录结构和对应的代码接口进行查看,便不难看出一二。
先看 ISoftBusClient 接口类
其中的接口方法就是主要的SDK中的对外接口。
再看ISoftBusServer
namespace OHOS {
class ISoftBusServer : public IRemoteBroker {
public:
virtual ~ISoftBusServer() = default;
virtual int32_t StartDiscovery(const char *pkgName, const SubscribeInfo *info) = 0;
virtual int32_t StopDiscovery(const char *pkgName, int subscribeId) = 0;
virtual int32_t PublishService(const char *pkgName, const PublishInfo *info) = 0;
virtual int32_t UnPublishService(const char *pkgName, int publishId) = 0;
virtual int32_t SoftbusRegisterService(const char *clientPkgName, const sptr<IRemoteObject> &object) = 0;
virtual int32_t CreateSessionServer(const char *pkgName, const char *sessionName) = 0;
virtual int32_t RemoveSessionServer(const char *pkgName, const char *sessionName) = 0;
virtual int32_t OpenSession(const SessionParam *param, TransInfo *info) = 0;
virtual int32_t OpenAuthSession(const char *sessionName, const ConnectionAddr *addrInfo) = 0;
virtual int32_t NotifyAuthSuccess(int channelId) = 0;
virtual int32_t CloseChannel(int32_t channelId, int32_t channelType) = 0;
virtual int32_t SendMessage(int32_t channelId, int32_t channelType,
const void *data, uint32_t len, int32_t msgType) = 0;
virtual int32_t JoinLNN(const char *pkgName, void *addr, uint32_t addrTypeLen) = 0;
virtual int32_t LeaveLNN(const char *pkgName, const char *networkId) = 0;
virtual int32_t GetAllOnlineNodeInfo(const char *pkgName, void **info, uint32_t infoTypeLen, int *infoNum) = 0;
virtual int32_t GetLocalDeviceInfo(const char *pkgName, void *info, uint32_t infoTypeLen) = 0;
virtual int32_t GetNodeKeyInfo(const char *pkgName, const char *networkId, int key, unsigned char *buf,
uint32_t len) = 0;
virtual int32_t StartTimeSync(const char *pkgName, const char *targetNetworkId, int32_t accuracy,
int32_t period) = 0;
virtual int32_t StopTimeSync(const char *pkgName, const char *targetNetworkId) = 0;
virtual int32_t QosReport(int32_t channelId, int32_t chanType, int32_t appType, int32_t quality) = 0;
virtual int32_t PublishLNN(const char *pkgName, const void *info, uint32_t infoTypeLen);
virtual int32_t StopPublishLNN(const char *pkgName, int32_t publishId);
virtual int32_t RefreshLNN(const char *pkgName, const void *info, uint32_t infoTypeLen);
virtual int32_t StopRefreshLNN(const char *pkgName, int32_t refreshId);
virtual int32_t ActiveMetaNode(const MetaNodeConfigInfo *info, char *metaNodeId);
virtual int32_t DeactiveMetaNode(const char *metaNodeId);
virtual int32_t GetAllMetaNodeInfo(MetaNodeInfo *info, int32_t *infoNum);
public:
DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.ISoftBusServer");
};
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
包括发现设备,发布服务,相当于这是系统自启动的一个服务。
解析一次调用链
对于proxy - client 架构,一般来说就是client调用sendRequest,server便会调用OnRemoteRequest,
我们直接从stub的方法入手分析下。
这里我们看到是使用不同的CODE做分发。
但是对外的接口都是c接口,c++接口中没有任何内容存储信息。这是为啥?这是为了兼容标准系统和其他系统。信息存储再统一的结构里面,然后根据不同的系统编译不同的.c或者.cpp文件。
咱们以joinLNN为例
实际调用的是joinLNNInner
先做了一些初始化的操作,查找当前节点是否存在。然后ServerIpcJoinLNN通信就是使用的proxy-stub侧的代码。
这里的关键就是g_serverProxy->JoinLNN(pkgName, addr, addrTypeLen);
实际调用的是
再看对应sub中SERVER_JOIN_LNN值去调用下面这个方法
可以看到显示读数据,然后调用JoinLNN,你发现stub这个方法为空,但是要注意到这个方法是一个虚函数
去查看它的子类SoftBusServer。
所以真正调用的是 LnnIpcServerJoin,我们看下他到底做了什么,这是真正的业务逻辑所在。
看一下,主要是有几个部分,第一查看参数有效性,第二是不是重复节点,使用连接地址创建连接,使用包名和地址建立映射。具体的感兴趣的小伙伴可以去查看一下。
大佬,好像前两张图挂了
我自己这边显示正常的
会不会是图片取到本地了,能麻烦大佬在上传下吗
666
优质内容,顶顶顶
66666
666666666666