软总线主节点选举算法

发布时间:2026/7/21 12:33:53
软总线主节点选举算法 一、权重计算公式LNN的权重计算采用设备类型基础权重 随机值的组合方式最终权重 设备类型基础权重 随机值(0~1000)二、设备类型基础权重表设备类型类型ID基础权重值TV电视0x9C8000Audio音响0x0A7000Car车机0x835000PC电脑0x044000Pad平板0x113000Phone手机0x0E2000其他/未知0x000权重优先级TV Audio Car PC Pad Phone 其他三、权重生成代码解析// 文件lnn_node_weight.c #define MAX_WEIGHT_VALUE 1000 // 随机值范围0~1000 #define BASE_WEIGHT_PHONE_VALUE 2000 // 手机基础权重 #define BASE_WEIGHT_PAD_VALUE 3000 // 平板基础权重 #define BASE_WEIGHT_TV_VALUE 8000 // 电视基础权重 #define BASE_WEIGHT_AUDIO_VALUE 7000 // 音响基础权重 #define BASE_WEIGHT_CAR_VALUE 5000 // 车机基础权重 #define BASE_WEIGHT_PC_VALUE 4000 // PC基础权重 int32_t LnnGetLocalWeight(void) { static int32_t weight; static bool isGenWeight false; // 权重只生成一次 uint8_t randVal 0; if (isGenWeight) { return weight; // 直接返回已生成的权重 } // 1. 生成0~1000的随机数 if (SoftBusGenerateRandomArray(randVal, sizeof(randVal)) ! SOFTBUS_OK) { return randVal; // 生成失败则返回随机值 } weight (int32_t)((randVal * MAX_WEIGHT_VALUE) / UINT8_MAX); // randVal/255 * 1000 // 2. 获取本机设备类型ID int32_t localDevTypeId 0; (void)LnnGetLocalNumInfo(NUM_KEY_DEV_TYPE_ID, localDevTypeId); // 3. 根据设备类型添加基础权重 switch (localDevTypeId) { case TYPE_PHONE_ID: weight BASE_WEIGHT_PHONE_VALUE; // 2000 break; case TYPE_PAD_ID: weight BASE_WEIGHT_PAD_VALUE; // 3000 break; case TYPE_TV_ID: weight BASE_WEIGHT_TV_VALUE; // 8000 break; case TYPE_AUDIO_ID: weight BASE_WEIGHT_AUDIO_VALUE; // 7000 break; case TYPE_CAR_ID: weight BASE_WEIGHT_CAR_VALUE; // 5000 break; case TYPE_PC_ID: weight BASE_WEIGHT_PC_VALUE; // 4000 break; default: break; // 其他类型不加基础权重 } isGenWeight true; // 标记已生成 return weight; }四、各设备权重范围设备类型权重范围TV8000 ~ 9000Audio7000 ~ 8000Car5000 ~ 6000PC4000 ~ 5000Pad3000 ~ 4000Phone2000 ~ 3000其他0 ~ 1000五、选举比较算法int32_t LnnCompareNodeWeight(int32_t weight1, const char *masterUdid1, int32_t weight2, const char *masterUdid2) { // 1. 首先比较权重 if (weight1 ! weight2) { return weight1 - weight2; // 差值为正weight1更大为负weight2更大 } // 2. 权重相同则比较UDID字典序 if (masterUdid1 NULL || masterUdid2 NULL) { return weight1 - weight2; } return strcmp(masterUdid1, masterUdid2); // UDID小者优先 }六、选举流程图七、选举消息同步// 同步选举消息给所有在线节点除了skipNetworkId void SendElectMessageToAll(const char *skipNetworkId) { LIST_FOR_EACH_ENTRY(item, g_netBuilder.fsmList, LnnConnectionFsm, node) { if (skipNetworkId ! NULL strcmp(item-connInfo.peerNetworkId, skipNetworkId) 0) { continue; // 跳过指定节点 } if (!IsNodeOnline(item-connInfo.peerNetworkId)) { continue; // 只同步给在线节点 } (void)SyncElectMessage(item-connInfo.peerNetworkId); } }八、设计优点优点说明设备类型优先TV、Audio等固定设备比手机等移动设备更适合作主节点随机性避免冲突同类型设备间通过随机值区分避免同时选举UDID保底权重和UDID都相同时UDID字典序小的优先最终一致性所有节点通过消息同步最终都会收敛到同一个主节点九、典型选举场景假设网络中有3个节点 节点A (Phone): weight 2000 500 2500 节点B (TV): weight 8000 300 8300 节点C (Pad): weight 3000 800 3800 选举结果节点B (TV) 当选为主节点 因为8300 3800 2500核心设计思想主节点选举算法综合考虑了设备稳定性TV/Audio等固定设备更适合作为主节点和公平性同类型设备间通过随机数区分。