HarmonyOS分布式组网APP开发实战
分布式组网:软总线连接流程
前面我们学习了软总线的基础原理和设备认证机制,这篇文章把这些知识串联起来,深入剖析分布式组网的完整流程。从设备发现到连接建立,从认证授权到数据传输,每一步都藏着精妙的设计。理解了这个流程,你就真正掌握了HarmonyOS分布式能力的"任督二脉"。
一、背景与动机:为什么需要分布式组网?
1.1 传统组网的局限
在传统IoT场景下,设备组网面临诸多挑战:
配置复杂:每个设备都需要单独配置网络参数、IP地址、端口映射……配置一套智能家居系统,可能需要花费数小时。
协议割裂:Wi-Fi设备、蓝牙设备、Zigbee设备各自为政,无法形成统一的网络拓扑。你的智能灯泡可能只能被网关控制,而无法直接被手机访问。
拓扑固定:传统网络拓扑相对固定,设备角色(主从、中继)难以动态调整。当某个设备离线时,可能导致整个网络瘫痪。
无状态感知:设备上线、下线、状态变化缺乏实时通知机制,应用层需要自己实现心跳检测。
1.2 HarmonyOS分布式组网的优势
HarmonyOS的分布式组网,构建了一个动态、自适应、安全的设备网络:

核心优势:
| 能力 | 说明 | 用户价值 |
|---|---|---|
| 自动发现 | 设备上电自动广播,无需手动搜索 | 即插即用 |
| 自动连接 | 基于信任关系自动建立连接 | 零配置 |
| 自动认证 | 同账号设备自动信任 | 无感认证 |
| 自动路由 | 智能选择最优通信路径 | 最佳体验 |
| 自动恢复 | 连接断开自动重连 | 高可用性 |
二、核心原理:分布式组网流程详解
2.1 组网流程全景图
分布式组网包含五个关键阶段:发现→认证→连接→会话→传输。
sequenceDiagram
participant DeviceA as 设备A(主控)
participant SoftBus as 软总线
participant Auth as 认证服务
participant Network as 网络服务
participant DeviceB as 设备B(被控)
Note over DeviceA,DeviceB: 阶段1:设备发现
DeviceA->>SoftBus: 启动设备发现
SoftBus->>Network: 广播发现请求
Network->>DeviceB: 发送广播
DeviceB->>Network: 发送设备信息
Network->>SoftBus: 收到设备信息
SoftBus-->>DeviceA: 发现设备B
Note over DeviceA,DeviceB: 阶段2:设备认证
DeviceA->>Auth: 发起认证请求
Auth->>DeviceB: 请求认证参数
DeviceB-->>Auth: 返回认证参数
Auth->>Auth: 执行认证流程
Auth-->>DeviceA: 认证成功
Note over DeviceA,DeviceB: 阶段3:连接建立
DeviceA->>SoftBus: 请求建立连接
SoftBus->>Network: 协商通信通道
Network->>DeviceB: 建立物理连接
DeviceB-->>Network: 连接就绪
Network-->>SoftBus: 连接建立成功
SoftBus-->>DeviceA: 连接成功通知
Note over DeviceA,DeviceB: 阶段4:会话创建
DeviceA->>SoftBus: 创建传输会话
SoftBus->>DeviceB: 创建会话请求
DeviceB->>DeviceB: 分配会话资源
DeviceB-->>SoftBus: 会话创建成功
SoftBus-->>DeviceA: 返回会话ID
Note over DeviceA,DeviceB: 阶段5:数据传输
DeviceA->>SoftBus: 发送数据
SoftBus->>Network: 数据封装与传输
Network->>DeviceB: 传输数据包
DeviceB->>DeviceB: 数据处理
DeviceB-->>Network: 返回响应
Network-->>SoftBus: 响应到达
SoftBus-->>DeviceA: 接收响应
classDef primary fill:#4A90E2,stroke:#2E5C8A,stroke-width:2px,color:#fff
classDef warning fill:#F5A623,stroke:#C17A00,stroke-width:2px,color:#fff
classDef info fill:#7ED321,stroke:#5BA315,stroke-width:2px,color:#fff
class DeviceA,DeviceB primary
class SoftBus,Auth,Network warning
2.2 阶段详解:设备发现
设备发现是组网的第一步,软总线采用多协议协同发现策略。
2.2.1 发现模式
// 发现模式定义
enum DiscoveryMode {
DISCOVER_MODE_PASSIVE = 0, // 被动模式:监听周围设备广播
DISCOVER_MODE_ACTIVE = 1 // 主动模式:主动广播并扫描
}
// 发现介质定义
enum DiscoveryMedium {
DISCOVER_MEDIUM_AUTO = 0, // 自动选择
DISCOVER_MEDIUM_BLE = 1, // 蓝牙BLE
DISCOVER_MEDIUM_COAP = 2, // CoAP(Wi-Fi)
DISCOVER_MEDIUM_BLE_COAP = 3 // BLE + CoAP
}
// 发现频率定义
enum DiscoveryFreq {
DISCOVER_FREQ_LOW = 0, // 低频(省电)
DISCOVER_FREQ_MID = 1, // 中频(平衡)
DISCOVER_FREQ_HIGH = 2 // 高频(快速)
}
2.2.2 发现流程详解

广播包结构:
// BLE广播包结构(31字节限制)
interface BleBroadcastPacket {
// 固定头部(7字节)
prefix: number; // 前缀标识(2字节)
version: number; // 协议版本(1字节)
deviceIdHash: number; // 设备ID哈希(4字节)
// 可变数据(最大24字节)
deviceType: number; // 设备类型(1字节)
capability: number; // 能力位图(2字节)
authType: number; // 认证类型(1字节)
networkId: number; // 网络ID哈希(4字节)
reserved: Uint8Array; // 预留扩展(最大16字节)
}
// CoAP组播消息结构
interface CoapMulticastMessage {
version: number; // 协议版本
messageType: number; // 消息类型
deviceId: string; // 完整设备ID
deviceName: string; // 设备名称
deviceType: number; // 设备类型
capability: number[]; // 能力列表
networkId: string; // 网络ID
port: number; // 服务端口
timestamp: number; // 时间戳
signature: string; // 数字签名
}
2.3 阶段详解:设备认证
发现设备后,需要进行认证建立信任关系。认证流程在上一篇文章已详细讲解,这里简要回顾:

2.4 阶段详解:连接建立
认证成功后,进入连接建立阶段。软总线会智能选择最优通信通道。
2.4.1 通道选择策略
// 通道类型定义
enum ConnectionChannel {
CHANNEL_BLE = 1, // 蓝牙BLE
CHANNEL_BR_EDR = 2, // 蓝牙BR/EDR
CHANNEL_WIFI_P2P = 3, // Wi-Fi P2P
CHANNEL_WIFI_STA = 4, // Wi-Fi STA(局域网)
CHANNEL_COAP = 5 // CoAP
}
// 通道能力定义
interface ChannelCapability {
channelType: ConnectionChannel;
maxBandwidth: number; // 最大带宽(KB/s)
avgLatency: number; // 平均延迟(ms)
powerConsumption: number; // 功耗等级(1-5)
reliability: number; // 可靠性等级(1-5)
available: boolean; // 是否可用
}
// 通道选择策略
function selectOptimalChannel(
channels: ChannelCapability[],
requirement: ConnectionRequirement
): ConnectionChannel {
// 根据需求权重计算得分
const scoredChannels = channels
.filter(ch => ch.available)
.map(ch => ({
channel: ch.channelType,
score: calculateScore(ch, requirement)
}))
.sort((a, b) => b.score - a.score);
return scoredChannels[0]?.channel || ConnectionChannel.CHANNEL_BLE;
}
// 计算通道得分
function calculateScore(
channel: ChannelCapability,
requirement: ConnectionRequirement
): number {
const weights = {
bandwidth: requirement.bandwidthWeight,
latency: requirement.latencyWeight,
power: requirement.powerWeight,
reliability: requirement.reliabilityWeight
};
// 归一化计算
const bandwidthScore = channel.maxBandwidth / 10000;
const latencyScore = 1 - (channel.avgLatency / 1000);
const powerScore = 1 - (channel.powerConsumption / 5);
const reliabilityScore = channel.reliability / 5;
return (
weights.bandwidth * bandwidthScore +
weights.latency * latencyScore +
weights.power * powerScore +
weights.reliability * reliabilityScore
);
}
2.4.2 连接建立流程
sequenceDiagram
participant DeviceA as 设备A
participant SoftBus as 软总线
participant Channel as 通道管理器
participant DeviceB as 设备B
DeviceA->>SoftBus: 请求连接设备B
SoftBus->>Channel: 查询可用通道
Channel->>Channel: 检测BLE通道
Channel->>Channel: 检测Wi-Fi通道
Channel->>Channel: 检测BR/EDR通道
Channel-->>SoftBus: 返回通道列表
SoftBus->>SoftBus: 选择最优通道
SoftBus->>DeviceB: 发送连接请求
alt Wi-Fi P2P连接
DeviceB->>DeviceB: 创建P2P组
DeviceB-->>SoftBus: 返回组信息
SoftBus->>DeviceA: 加入P2P组
DeviceA->>DeviceB: 完成P2P连接
else 蓝牙BR/EDR连接
DeviceB->>DeviceB: 开启RFCOMM服务
DeviceB-->>SoftBus: 返回通道号
SoftBus->>DeviceA: 连接RFCOMM
DeviceA->>DeviceB: 完成蓝牙连接
else BLE连接
DeviceB->>DeviceB: 开启GATT服务
DeviceB-->>SoftBus: 返回服务UUID
SoftBus->>DeviceA: 连接GATT
DeviceA->>DeviceB: 完成BLE连接
end
DeviceB-->>SoftBus: 连接建立成功
SoftBus-->>DeviceA: 连接就绪通知
classDef primary fill:#4A90E2,stroke:#2E5C8A,stroke-width:2px,color:#fff
classDef warning fill:#F5A623,stroke:#C17A00,stroke-width:2px,color:#fff
classDef info fill:#7ED321,stroke:#5BA315,stroke-width:2px,color:#fff
class DeviceA,DeviceB primary
class SoftBus,Channel warning
2.5 阶段详解:会话管理
连接建立后,需要创建会话进行数据传输。
2.5.1 会话模型
// 会话定义
interface Session {
sessionId: string; // 会话唯一标识
deviceId: string; // 对端设备ID
channelType: ConnectionChannel; // 使用的通道类型
sessionType: SessionType; // 会话类型
state: SessionState; // 会话状态
config: SessionConfig; // 会话配置
statistics: SessionStatistics; // 会话统计
}
// 会话类型
enum SessionType {
SESSION_TYPE_RAW = 0, // 原始数据会话
SESSION_TYPE_MESSAGE = 1, // 消息会话(可靠)
SESSION_TYPE_FILE = 2, // 文件传输会话
SESSION_TYPE_STREAM = 3 // 流传输会话
}
// 会话状态
enum SessionState {
SESSION_STATE_NONE = 0, // 未创建
SESSION_STATE_OPENING = 1, // 创建中
SESSION_STATE_OPENED = 2, // 已创建
SESSION_STATE_CLOSING = 3, // 关闭中
SESSION_STATE_CLOSED = 4 // 已关闭
}
// 会话配置
interface SessionConfig {
mtu: number; // 最大传输单元
sendWindowSize: number; // 发送窗口大小
recvWindowSize: number; // 接收窗口大小
timeout: number; // 超时时间
retryCount: number; // 重试次数
qosLevel: QosLevel; // QoS等级
}
// 会话统计
interface SessionStatistics {
sendBytes: number; // 发送字节数
recvBytes: number; // 接收字节数
sendPackets: number; // 发送包数
recvPackets: number; // 接收包数
lostPackets: number; // 丢包数
avgLatency: number; // 平均延迟
maxLatency: number; // 最大延迟
}
2.6 阶段详解:数据传输
会话创建后,就可以进行数据传输了。
2.6.1 数据传输流程

三、代码实战:完整组网流程
3.1 组网管理器实现
import deviceManager from '@ohos.distributedHardware.deviceManager';
import { ConnectionManager, ConnectionState } from '@ohos.distributedHardware.connectionManager';
import { DataTransmitManager } from '@ohos.distributedHardware.dataTransmit';
/**
* 分布式组网管理器
* 封装完整的组网流程
*/
export class DistributedNetworkManager {
private deviceMgr: deviceManager.DeviceManager | null = null;
private connectionMgr: ConnectionManager | null = null;
private transmitMgr: DataTransmitManager | null = null;
private discoveredDevices: Map<string, DeviceInfo> = new Map();
private connections: Map<string, ConnectionInfo> = new Map();
private sessions: Map<string, SessionInfo> = new Map();
private state: NetworkState = NetworkState.DISCONNECTED;
private listeners: Set<NetworkStateListener> = new Set();
/**
* 初始化组网管理器
*/
async initialize(bundleName: string): Promise<void> {
try {
// 创建各管理器实例
this.deviceMgr = deviceManager.createDeviceManager(bundleName);
this.connectionMgr = ConnectionManager.create();
this.transmitMgr = DataTransmitManager.create();
// 注册事件监听
this.registerEventListeners();
console.info('[Network] 组网管理器初始化成功');
} catch (error) {
console.error(`[Network] 初始化失败: ${JSON.stringify(error)}`);
throw error;
}
}
/**
* 注册事件监听
*/
private registerEventListeners(): void {
// 设备发现监听
this.deviceMgr?.on('deviceFound', (data) => {
this.handleDeviceFound(data.device);
});
this.deviceMgr?.on('deviceLost', (data) => {
this.handleDeviceLost(data.deviceId);
});
// 连接状态监听
this.connectionMgr?.on('connectionStateChanged', (info) => {
this.handleConnectionStateChange(info);
});
// 会话状态监听
this.transmitMgr?.on('sessionStateChanged', (info) => {
this.handleSessionStateChange(info);
});
}
/**
* 启动组网
* 自动发现并连接可信设备
*/
async startNetworking(): Promise<void> {
if (!this.deviceMgr) {
throw new Error('组网管理器未初始化');
}
this.updateState(NetworkState.DISCOVERING);
try {
// 启动设备发现
const subscribeId = await this.deviceMgr.startDeviceDiscovery({
subscribeId: this.generateSubscribeId(),
mode: deviceManager.DISCOVER_MODE_ACTIVE,
medium: deviceManager.DISCOVER_MEDIUM_AUTO,
freq: deviceManager.DISCOVER_FREQ_MID,
isSameAccount: false,
isWakeRemote: true
});
console.info(`[Network] 开始设备发现,订阅ID: ${subscribeId}`);
// 等待一段时间收集设备
await this.waitForDiscovery(5000);
// 自动连接可信设备
await this.autoConnectTrustedDevices();
} catch (error) {
console.error(`[Network] 组网启动失败: ${JSON.stringify(error)}`);
this.updateState(NetworkState.ERROR);
}
}
/**
* 等待设备发现
*/
private waitForDiscovery(timeout: number): Promise<void> {
return new Promise(resolve => {
setTimeout(resolve, timeout);
});
}
/**
* 自动连接可信设备
*/
private async autoConnectTrustedDevices(): Promise<void> {
// 获取可信设备列表
const trustedDevices = await this.deviceMgr?.getTrustedDeviceList(true) || [];
console.info(`[Network] 发现${trustedDevices.length}个可信设备`);
// 并行连接所有可信设备
const connectPromises = trustedDevices.map(device =>
this.connectDevice(device.deviceId).catch(error => {
console.error(`[Network] 连接设备失败: ${device.deviceId}, ${error}`);
})
);
await Promise.all(connectPromises);
// 更新状态
if (this.connections.size > 0) {
this.updateState(NetworkState.CONNECTED);
} else {
this.updateState(NetworkState.DISCONNECTED);
}
}
/**
* 连接指定设备
*/
async connectDevice(deviceId: string): Promise<boolean> {
if (!this.connectionMgr) {
throw new Error('连接管理器未初始化');
}
// 检查是否已连接
if (this.connections.has(deviceId)) {
console.info(`[Network] 设备已连接: ${deviceId}`);
return true;
}
try {
console.info(`[Network] 开始连接设备: ${deviceId}`);
// 发起连接
await this.connectionMgr.connect({
deviceId: deviceId,
authType: 'AUTH_TYPE_ACCOUNT',
priority: 'PRIORITY_HIGH'
});
// 等待连接完成
const connected = await this.waitForConnection(deviceId, 10000);
if (connected) {
console.info(`[Network] 设备连接成功: ${deviceId}`);
return true;
} else {
console.error(`[Network] 设备连接超时: ${deviceId}`);
return false;
}
} catch (error) {
console.error(`[Network] 连接异常: ${JSON.stringify(error)}`);
return false;
}
}
/**
* 等待连接完成
*/
private waitForConnection(deviceId: string, timeout: number): Promise<boolean> {
return new Promise(resolve => {
const startTime = Date.now();
const check = () => {
const connection = this.connections.get(deviceId);
if (connection?.state === ConnectionState.STATE_CONNECTED) {
resolve(true);
return;
}
if (Date.now() - startTime >= timeout) {
resolve(false);
return;
}
setTimeout(check, 100);
};
check();
});
}
/**
* 创建传输会话
*/
async createSession(deviceId: string): Promise<string> {
if (!this.transmitMgr) {
throw new Error('传输管理器未初始化');
}
// 检查连接状态
const connection = this.connections.get(deviceId);
if (!connection || connection.state !== ConnectionState.STATE_CONNECTED) {
throw new Error('设备未连接');
}
try {
// 创建会话
const sessionId = await this.transmitMgr.createSession({
deviceId: deviceId,
sessionType: 'SESSION_TYPE_MESSAGE',
dataType: 'DATA_TYPE_BYTES'
});
// 保存会话信息
this.sessions.set(sessionId, {
sessionId: sessionId,
deviceId: deviceId,
state: SessionState.OPENED
});
console.info(`[Network] 会话创建成功: ${sessionId}`);
return sessionId;
} catch (error) {
console.error(`[Network] 会话创建失败: ${JSON.stringify(error)}`);
throw error;
}
}
/**
* 发送数据
*/
async sendData(sessionId: string, data: Uint8Array): Promise<void> {
if (!this.transmitMgr) {
throw new Error('传输管理器未初始化');
}
const session = this.sessions.get(sessionId);
if (!session) {
throw new Error('会话不存在');
}
try {
await this.transmitMgr.sendData({
sessionId: sessionId,
data: data,
option: {
priority: 'PRIORITY_HIGH',
needAck: true,
timeout: 5000
}
});
console.info(`[Network] 数据发送成功,大小: ${data.length}字节`);
} catch (error) {
console.error(`[Network] 数据发送失败: ${JSON.stringify(error)}`);
throw error;
}
}
/**
* 断开设备连接
*/
async disconnectDevice(deviceId: string): Promise<void> {
if (!this.connectionMgr) {
return;
}
try {
// 关闭所有会话
for (const [sessionId, session] of this.sessions) {
if (session.deviceId === deviceId) {
await this.transmitMgr?.closeSession(sessionId);
this.sessions.delete(sessionId);
}
}
// 断开连接
await this.connectionMgr.disconnect(deviceId);
this.connections.delete(deviceId);
console.info(`[Network] 设备已断开: ${deviceId}`);
// 更新状态
if (this.connections.size === 0) {
this.updateState(NetworkState.DISCONNECTED);
}
} catch (error) {
console.error(`[Network] 断开连接失败: ${JSON.stringify(error)}`);
}
}
/**
* 停止组网
*/
async stopNetworking(): Promise<void> {
// 断开所有设备
const disconnectPromises = Array.from(this.connections.keys()).map(
deviceId => this.disconnectDevice(deviceId)
);
await Promise.all(disconnectPromises);
// 停止设备发现
if (this.deviceMgr) {
await this.deviceMgr.stopDeviceDiscovery(this.currentSubscribeId);
}
this.updateState(NetworkState.DISCONNECTED);
console.info('[Network] 组网已停止');
}
/**
* 处理设备发现
*/
private handleDeviceFound(device: DeviceInfo): void {
this.discoveredDevices.set(device.deviceId, device);
console.info(`[Network] 发现设备: ${device.deviceName} (${device.deviceId})`);
// 通知监听器
this.notifyListeners({
type: 'deviceFound',
device: device
});
}
/**
* 处理设备丢失
*/
private handleDeviceLost(deviceId: string): void {
this.discoveredDevices.delete(deviceId);
console.info(`[Network] 设备离线: ${deviceId}`);
// 通知监听器
this.notifyListeners({
type: 'deviceLost',
deviceId: deviceId
});
}
/**
* 处理连接状态变化
*/
private handleConnectionStateChange(info: ConnectionStateInfo): void {
const { deviceId, state } = info;
// 更新连接信息
this.connections.set(deviceId, {
deviceId: deviceId,
state: state
});
console.info(`[Network] 连接状态变化: ${deviceId} -> ${state}`);
// 通知监听器
this.notifyListeners({
type: 'connectionStateChanged',
deviceId: deviceId,
state: state
});
}
/**
* 处理会话状态变化
*/
private handleSessionStateChange(info: SessionStateInfo): void {
const { sessionId, state } = info;
const session = this.sessions.get(sessionId);
if (session) {
session.state = state;
}
console.info(`[Network] 会话状态变化: ${sessionId} -> ${state}`);
// 通知监听器
this.notifyListeners({
type: 'sessionStateChanged',
sessionId: sessionId,
state: state
});
}
/**
* 更新网络状态
*/
private updateState(state: NetworkState): void {
this.state = state;
this.notifyListeners({
type: 'networkStateChanged',
state: state
});
}
/**
* 添加状态监听器
*/
addStateListener(listener: NetworkStateListener): void {
this.listeners.add(listener);
}
/**
* 移除状态监听器
*/
removeStateListener(listener: NetworkStateListener): void {
this.listeners.delete(listener);
}
/**
* 通知所有监听器
*/
private notifyListeners(event: NetworkEvent): void {
this.listeners.forEach(listener => {
listener.onNetworkEvent(event);
});
}
/**
* 生成订阅ID
*/
private generateSubscribeId(): string {
return Math.random().toString(36).substring(2, 10);
}
private currentSubscribeId: string = '';
/**
* 获取网络状态
*/
getState(): NetworkState {
return this.state;
}
/**
* 获取已发现设备列表
*/
getDiscoveredDevices(): DeviceInfo[] {
return Array.from(this.discoveredDevices.values());
}
/**
* 获取已连接设备列表
*/
getConnectedDevices(): string[] {
return Array.from(this.connections.keys());
}
/**
* 释放资源
*/
release(): void {
// 取消所有事件监听
this.deviceMgr?.off('deviceFound');
this.deviceMgr?.off('deviceLost');
this.connectionMgr?.off('connectionStateChanged');
this.transmitMgr?.off('sessionStateChanged');
// 清空数据
this.discoveredDevices.clear();
this.connections.clear();
this.sessions.clear();
this.listeners.clear();
console.info('[Network] 资源已释放');
}
}
// 网络状态枚举
enum NetworkState {
DISCONNECTED = 0, // 未连接
DISCOVERING = 1, // 发现中
CONNECTING = 2, // 连接中
CONNECTED = 3, // 已连接
ERROR = 4 // 错误
}
// 网络事件类型
type NetworkEvent = {
type: 'deviceFound';
device: DeviceInfo;
} | {
type: 'deviceLost';
deviceId: string;
} | {
type: 'connectionStateChanged';
deviceId: string;
state: ConnectionState;
} | {
type: 'sessionStateChanged';
sessionId: string;
state: SessionState;
} | {
type: 'networkStateChanged';
state: NetworkState;
};
// 状态监听器接口
interface NetworkStateListener {
onNetworkEvent(event: NetworkEvent): void;
}
3.2 组网状态监控组件
/**
* 组网状态监控组件
* 实时显示组网状态和设备信息
*/
@Component
export struct NetworkMonitorPanel {
@State networkState: NetworkState = NetworkState.DISCONNECTED;
@State discoveredDevices: DeviceInfo[] = [];
@State connectedDevices: string[] = [];
private networkManager: DistributedNetworkManager | null = null;
aboutToAppear(): void {
this.initializeNetwork();
}
/**
* 初始化网络
*/
private async initializeNetwork(): Promise<void> {
this.networkManager = new DistributedNetworkManager();
await this.networkManager.initialize('com.example.app');
// 添加状态监听
this.networkManager.addStateListener({
onNetworkEvent: (event) => {
this.handleNetworkEvent(event);
}
});
// 启动组网
await this.networkManager.startNetworking();
}
/**
* 处理网络事件
*/
private handleNetworkEvent(event: NetworkEvent): void {
switch (event.type) {
case 'networkStateChanged':
this.networkState = event.state;
break;
case 'deviceFound':
this.discoveredDevices = this.networkManager?.getDiscoveredDevices() || [];
break;
case 'deviceLost':
this.discoveredDevices = this.networkManager?.getDiscoveredDevices() || [];
break;
case 'connectionStateChanged':
this.connectedDevices = this.networkManager?.getConnectedDevices() || [];
break;
}
}
build() {
Column() {
// 网络状态标题
Row() {
Text('分布式组网状态')
.fontSize(20)
.fontWeight(FontWeight.Bold)
Blank()
// 状态指示器
Circle()
.width(12)
.height(12)
.fill(this.getStateColor())
}
.width('100%')
.padding(16)
Divider()
// 状态信息
Column() {
this.StateInfoRow('网络状态', this.getStateText())
this.StateInfoRow('已发现设备', `${this.discoveredDevices.length}个`)
this.StateInfoRow('已连接设备', `${this.connectedDevices.length}个`)
}
.padding(16)
Divider()
// 设备列表
Column() {
Text('已连接设备')
.fontSize(16)
.fontWeight(FontWeight.Medium)
.width('100%')
.margin({ bottom: 8 })
ForEach(this.connectedDevices, (deviceId: string) => {
this.ConnectedDeviceItem(deviceId)
}, (deviceId: string) => deviceId)
}
.padding(16)
.alignItems(HorizontalAlign.Start)
}
.width('100%')
.backgroundColor('#F5F5F5')
.borderRadius(12)
}
@Builder
StateInfoRow(label: string, value: string) {
Row() {
Text(label)
.fontSize(14)
.fontColor('#666666')
Blank()
Text(value)
.fontSize(14)
.fontColor('#333333')
}
.width('100%')
.margin({ bottom: 8 })
}
@Builder
ConnectedDeviceItem(deviceId: string) {
Row() {
Text(deviceId.substring(0, 8))
.fontSize(14)
.fontColor('#333333')
Blank()
Button('断开')
.fontSize(12)
.height(28)
.onClick(() => {
this.networkManager?.disconnectDevice(deviceId);
})
}
.width('100%')
.padding({ vertical: 8 })
}
/**
* 获取状态文本
*/
private getStateText(): string {
const stateMap = {
[NetworkState.DISCONNECTED]: '未连接',
[NetworkState.DISCOVERING]: '发现中',
[NetworkState.CONNECTING]: '连接中',
[NetworkState.CONNECTED]: '已连接',
[NetworkState.ERROR]: '错误'
};
return stateMap[this.networkState] || '未知';
}
/**
* 获取状态颜色
*/
private getStateColor(): ResourceColor {
const colorMap = {
[NetworkState.DISCONNECTED]: '#999999',
[NetworkState.DISCOVERING]: '#F5A623',
[NetworkState.CONNECTING]: '#F5A623',
[NetworkState.CONNECTED]: '#7ED321',
[NetworkState.ERROR]: '#D0021B'
};
return colorMap[this.networkState] || '#999999';
}
aboutToDisappear(): void {
this.networkManager?.release();
}
}
四、踩坑与注意事项
4.1 组网流程相关
坑1:设备发现未完成就尝试连接
// ❌ 错误做法:立即连接
await deviceMgr.startDeviceDiscovery(params);
await connectionMgr.connect(deviceId); // 可能设备还未被发现
// ✅ 正确做法:等待设备发现
await deviceMgr.startDeviceDiscovery(params);
await waitForDevice(deviceId, 5000); // 等待设备被发现
await connectionMgr.connect(deviceId);
坑2:连接失败未重试
// ✅ 正确做法:实现重试机制
async connectWithRetry(deviceId: string, maxRetries: number = 3): Promise<boolean> {
for (let i = 0; i < maxRetries; i++) {
try {
const success = await this.connectDevice(deviceId);
if (success) {
return true;
}
} catch (error) {
console.error(`连接失败,第${i + 1}次重试`);
}
// 等待一段时间再重试
await new Promise(resolve => setTimeout(resolve, 2000));
}
return false;
}
4.2 性能相关
坑3:并发连接过多
同时连接过多设备会消耗大量资源。
// ✅ 正确做法:限制并发连接数
async connectDevicesWithLimit(
deviceIds: string[],
maxConcurrent: number = 3
): Promise<void> {
const batches: string[][] = [];
for (let i = 0; i < deviceIds.length; i += maxConcurrent) {
batches.push(deviceIds.slice(i, i + maxConcurrent));
}
for (const batch of batches) {
await Promise.all(batch.map(id => this.connectDevice(id)));
}
}
4.3 稳定性相关
坑4:连接断开未处理
// ✅ 正确做法:监听连接状态并自动重连
connectionMgr.on('connectionStateChanged', async (info) => {
if (info.state === ConnectionState.STATE_DISCONNECTED) {
console.info(`连接断开,尝试重连: ${info.deviceId}`);
// 延迟重连
setTimeout(() => {
this.connectDevice(info.deviceId);
}, 3000);
}
});
五、HarmonyOS 6适配指南
5.1 API变更
组网API重构:
// HarmonyOS 6.0新增统一组网接口
import { DistributedNetwork } from '@ohos.distributedHardware.network';
const network = DistributedNetwork.getInstance();
// 一键组网
await network.startNetworking({
autoDiscover: true,
autoConnect: true,
autoReconnect: true,
discoveryFilter: {
deviceTypes: [DeviceType.PHONE, DeviceType.TABLET]
}
});
5.2 行为变更
变更1:组网状态机增强
HarmonyOS 6新增了更细粒度的组网状态。
// HarmonyOS 6新增状态
enum NetworkStateV6 {
IDLE = 0, // 空闲
DISCOVERING = 1, // 发现中
AUTHENTICATING = 2, // 认证中(新增)
CONNECTING = 3, // 连接中
CONNECTED = 4, // 已连接
RECOVERING = 5, // 恢复中(新增)
ERROR = 6 // 错误
}
变更2:智能路由增强
// HarmonyOS 6新增智能路由配置
await network.configureRouting({
strategy: 'OPTIMAL', // 最优策略
preferBandwidth: false, // 不优先带宽
preferLatency: true, // 优先延迟
preferPower: false // 不优先功耗
});
六、总结
分布式组网是HarmonyOS分布式能力的核心流程,它将设备发现、认证、连接、会话、传输串联起来,形成完整的设备通信链路。
核心要点回顾:
- 组网流程:发现→认证→连接→会话→传输
- 设备发现:多协议协同发现,BLE + CoAP
- 连接建立:智能通道选择,自动协商最优路径
- 会话管理:多会话复用,流量控制
- 数据传输:分片、加密、压缩、可靠传输
最佳实践建议:
- 等待设备发现完成后再连接
- 实现连接失败重试机制
- 限制并发连接数量
- 监听连接状态并自动重连
- 使用兼容层适配多版本API
理解了分布式组网流程,你就掌握了构建分布式应用的核心能力。
- 点赞
- 收藏
- 关注作者
评论(0)