HarmonyOS分布式组网APP开发实战

举报
Jack20 发表于 2026/06/19 20:43:57 2026/06/19
【摘要】 分布式组网:软总线连接流程前面我们学习了软总线的基础原理和设备认证机制,这篇文章把这些知识串联起来,深入剖析分布式组网的完整流程。从设备发现到连接建立,从认证授权到数据传输,每一步都藏着精妙的设计。理解了这个流程,你就真正掌握了HarmonyOS分布式能力的"任督二脉"。 一、背景与动机:为什么需要分布式组网? 1.1 传统组网的局限在传统IoT场景下,设备组网面临诸多挑战:配置复杂:每个...

分布式组网:软总线连接流程

前面我们学习了软总线的基础原理和设备认证机制,这篇文章把这些知识串联起来,深入剖析分布式组网的完整流程。从设备发现到连接建立,从认证授权到数据传输,每一步都藏着精妙的设计。理解了这个流程,你就真正掌握了HarmonyOS分布式能力的"任督二脉"。

一、背景与动机:为什么需要分布式组网?

1.1 传统组网的局限

在传统IoT场景下,设备组网面临诸多挑战:

配置复杂:每个设备都需要单独配置网络参数、IP地址、端口映射……配置一套智能家居系统,可能需要花费数小时。

协议割裂:Wi-Fi设备、蓝牙设备、Zigbee设备各自为政,无法形成统一的网络拓扑。你的智能灯泡可能只能被网关控制,而无法直接被手机访问。

拓扑固定:传统网络拓扑相对固定,设备角色(主从、中继)难以动态调整。当某个设备离线时,可能导致整个网络瘫痪。

无状态感知:设备上线、下线、状态变化缺乏实时通知机制,应用层需要自己实现心跳检测。

1.2 HarmonyOS分布式组网的优势

HarmonyOS的分布式组网,构建了一个动态、自适应、安全的设备网络:
图片.png

核心优势

能力 说明 用户价值
自动发现 设备上电自动广播,无需手动搜索 即插即用
自动连接 基于信任关系自动建立连接 零配置
自动认证 同账号设备自动信任 无感认证
自动路由 智能选择最优通信路径 最佳体验
自动恢复 连接断开自动重连 高可用性

二、核心原理:分布式组网流程详解

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 发现流程详解

图片.png

广播包结构

// 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 阶段详解:设备认证

发现设备后,需要进行认证建立信任关系。认证流程在上一篇文章已详细讲解,这里简要回顾:

图片.png

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 数据传输流程

图片.png

三、代码实战:完整组网流程

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分布式能力的核心流程,它将设备发现、认证、连接、会话、传输串联起来,形成完整的设备通信链路。

核心要点回顾

  1. 组网流程:发现→认证→连接→会话→传输
  2. 设备发现:多协议协同发现,BLE + CoAP
  3. 连接建立:智能通道选择,自动协商最优路径
  4. 会话管理:多会话复用,流量控制
  5. 数据传输:分片、加密、压缩、可靠传输

最佳实践建议

  • 等待设备发现完成后再连接
  • 实现连接失败重试机制
  • 限制并发连接数量
  • 监听连接状态并自动重连
  • 使用兼容层适配多版本API

理解了分布式组网流程,你就掌握了构建分布式应用的核心能力。


【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。