# BLE蓝牙客户端连接后无法接收服务端广播数据

#### 问题现象

BLE蓝牙服务端和客户端连接成功后，客户端收到服务端约30次数据后停止接收。

#### 背景知识

*   低功耗蓝牙（Bluetooth Low Energy, BLE）是从蓝牙4.0开始支持的技术。相比于传统蓝牙，BLE在保障一定的传输速率情况下，具备更低功耗的特点，广泛使用于续航要求较高的蓝牙设备中。其最高传输速率可达1Mbps，通信范围通常为10米左右。相比于传统蓝牙，BLE以其低功耗的特点，广泛应用于穿戴设备、智能家居和物联网传感器等领域。
*   notifyCharacteristicChanged：server端发送特征值变化通知或者指示给client端。
*   on('descriptorWrite')：server端订阅client的描述符写请求事件，server端收到该事件后需要根据DescriptorWriteRequest里的needRsp决定是否调用sendResponse接口回复client。

#### 问题定位

定位思路：

先排查服务端是否正常广播数据，以下日志表示服务端广播日志正常打印：

再排查客户端是否正常接收数据，发现客户端BLECharacteristicChanges事件回调日志打印到第30次后结束打印。

蓝牙中的Hilog日志显示客户端NotifyCallback同样只执行30次。

翻看BLE蓝牙服务端文档发现，当服务端收到写入描述符请求时，根据写入请求DescriptorWriteRequest的needRsp判断是否需要调用sendResponse进行回复。根据文档说明可知，服务端需要订阅客户端的描述符写请求事件，即server.on('descriptorWrite')，当客户端发起写入描述符请求事件descriptorWrite时，可通过在服务端监听descriptorWrite事件，并在回调中回复客户端。

#### 分析结论

根据分析以上定位过程可知，造成客户端无法接收服务端广播数据的原因是服务端没有监听客户端发起写入描述符请求事件descriptorWrite。

#### 修改建议

服务端在数据传输阶段监听descriptorWrite事件。

验证结果可以看出客户端的BLECharacteristicChange回调函数已经持续执行超过30次。

#### 总结

通过订阅描述符读取或写入事件请参考on('descriptorRead')和on('descriptorWrite')。

收到读取描述符请求时，需要调用sendResponse进行回复对应描述符的数据内容。

收到写入描述符请求时，可保存客户端写入的描述符数据内容。根据写入请求DescriptorWriteRequest的needRsp判断是否需要调用sendResponse进行回复。