Uniapp跨平台蓝牙多设备并发管理模型
一、核心设计原则
统一设备池管理
使用中心化设备池管理所有连接状态:const devicePool = new Map(); // 结构:{ deviceId: { state, characteristics, queue } }
异步任务队列
每个设备独立维护指令队列:class DeviceQueue {constructor() {this.pending = []; // 待执行队列this.executing = null; // 当前执行任务}add(task) { /* ... */ } // 添加任务 }
连接数动态调控
平台自适应连接策略:function checkConnectionLimit() {// iOS限制7个,Android可扩展const max = uni.getSystemInfoSync().platform === 'ios' ? 7 : 15;return devicePool.size >= max ? false : true; }
二、并发控制模型
graph TDA[设备发现] --> B{连接池检查}B -->|可连接| C[创建设备实例]B -->|已达上限| D[触发LRU淘汰]C --> E[初始化指令队列]E --> F[注册全局监听]F --> G[加入设备池]
三、关键实现代码
- 设备连接管理
async function connectDevice(deviceId) {if (!checkConnectionLimit()) throw new Error('CONNECTION_LIMIT');const device = {id: deviceId,state: 'connecting',queue: new DeviceQueue(),services: {}};await uni.createBLEConnection({ deviceId });const services = await uni.getBLEDeviceServices({ deviceId });services.forEach(service => {device.services[service.uuid] = {characteristics: await getCharacteristics(deviceId, service.uuid)};});devicePool.set(deviceId, device);return device;
}
- 数据收发控制器
function createCommunicationHandler(deviceId) {return {send: (data, serviceUUID, charUUID) => {return new Promise((resolve) => {devicePool.get(deviceId).queue.add({action: () => uni.writeBLECharacteristicValue({deviceId,serviceId: serviceUUID,characteristicId: charUUID,value: data}),resolve});});},listen: (charUUID, callback) => {uni.onBLECharacteristicValueChange(res => {if (res.deviceId === deviceId && res.characteristicId === charUUID) {callback(res.value);}});}};
}
四、性能优化策略
连接复用机制
- 心跳维持:每30秒发送心跳包保持连接 $$ \text{心跳间隔} \Delta t = 30\text{s} $$
- 自动重连:指数退避算法重连 $$ \text{重连间隔} = 2^n \times \text{基础间隔} \quad (n \in \mathbb{N}) $$
数据压缩传输
使用Protocol Buffers编码:message BleCommand {required uint32 opcode = 1;optional bytes payload = 2; }
异常处理框架
const errorHandler = {'10001': () => refreshBluetoothAdapter(),'10003': deviceId => reconnectDevice(deviceId),'default': err => uni.showToast({ title: err.errMsg })
};uni.onBLEConnectionStateChange(({ deviceId, connected }) => {if (!connected) errorHandler['10003'](deviceId);
});
五、平台差异处理
特性 | iOS方案 | Android方案 |
---|---|---|
后台运行 | CoreBluetooth后台模式 | Foreground Service |
连接数限制 | 7个 | 理论无上限 |
设备发现 | 需触发startDiscovery | 持续监听广播 |
六、最佳实践建议
设备分级策略
- 关键设备:保持永久连接
- 次要设备:按需连接
const devicePriority = {HEART_MONITOR: 1,THERMOMETER: 2,STEP_COUNTER: 3 };
数据分片传输
大数据包分片处理:function fragmentData(data, chunkSize = 20) {const chunks = [];for (let i = 0; i < data.length; i += chunkSize) {chunks.push(data.slice(i, i + chunkSize));}return chunks; }
连接状态同步
使用Vuex全局状态管理:const store = new Vuex.Store({state: { connectedDevices: [] },mutations: {updateDeviceState(state, { deviceId, state }) {const index = state.connectedDevices.findIndex(d => d.id === deviceId);if (index !== -1) {Vue.set(state.connectedDevices, index, { ...state.connectedDevices[index], state });}}} });
注意事项:
- 安卓设备需动态申请
BLUETOOTH_CONNECT
权限- iOS需在Info.plist添加
NSBluetoothAlwaysUsageDescription
- 多设备场景避免频繁扫描(每次扫描间隔≥2秒)