智能家庭蓝牙框架优化的思考

来源:互联网 发布:网络rtt 编辑:程序博客网 时间:2024/04/28 03:53

蓝牙可以分为两大块,扫描和连接。其实没有别的,直接调用系统接口就可以了,然而为什么要形成一套框架,主要原因还是为了适应业务的变化。比如蓝牙扫描,如果要同时扫经典蓝牙和ble,该采用什么策略,如果有一天策略调整了怎么办,能否快速适应。还有ble广播的扫描策略是独立于设备扫描的,极端点需要高频扫描(扫30次,每次1s),而设备扫描可能是扫30s,一次就够了。如果扫描正在进行中,又来了新的扫描任务该怎么办?是否需要引入扫描事务的概念?再比如蓝牙连接,如果当前任务尚未完成,又来一个数据读写任务怎么办?如果任务超时或失败怎么办?如果数据需要加密怎么办?来了新业务是否能很快支持,业务变动了也基本不用怎么动代码。这些都是框架需要考虑的问题。

先谈谈扫描的调度方式,总结了一下,有四种:抢占式、排他式、借宿式、队列式。
抢占式:如果有其它任务进行中,则stop掉旧任务,启动新任务
排他式:如果有其它任务进行中,则什么也不干,直接返回
借宿式:如果有其它任务进行中,则借用该任务的已扫描到的结果
队列式:如果有其它任务进行中,则入队列,按先后顺序依次执行

到底框架支持哪种呢?
我选择的是抢占式,原因有两点,一个是抢占式最简单,而框架很重要的一个原则就是要简单可靠。处理任务时,先判断当前是否有正在运行的任务,如果有就cancel掉,然后启动新任务。无需有其它的逻辑,非常简单。因为简单,所以不容易出问题,并且出问题的时候也很容易定位。另一个原因就是其它的调度方式都可以基于抢占式,在上层进行封装来实现。当逻辑很多的时候,与其都硬塞到一起,不如进行分层,最核心最可靠与业务无关的部分放在最底层,其余的可以放在上层。底层的东西稳定了就不用再动了,变动的是上层。

再谈谈蓝牙的连接和读写问题,蓝牙要进行数据读写,有这么几个步骤,首先要建立连接,然后再获取service,然后再数据读写。这三个步骤都是异步的,任何一个步骤都可能失败,或者干脆收不到回调,那就意味着如果没有超时机制的话就得永远等下去,这是不可忍受的。所以为了整个流程可靠,需要增加任务失败和任务超时的处理。这只是一次数据读写,而真实情况是与设备交互涉及到来来回回若干次读写,所以可以想象到有多复杂,如果没有一套框架来处理这些任务,那得有多让人抓狂。

框架用来为每个设备维护一个任务队列,任务包括连接,断开连接,读,写,打开notify,关闭notify等。
每个任务都有对应的回调,并且会进行失败处理和超时控制,相当于在系统API上封装了一层。如果要对数据加密,也可以很容易地集成到框架中。

此外,蓝牙扫描和设备读写也不是分立的。当蓝牙扫描时,任何设备读写操作都需要挂起。当设备读写时,蓝牙扫描也需要挂起,这也需要框架进行统筹规划。

最后,大概列一下框架的优化点:
一、完善日志记录,找问题时有迹可循
二、扫描事务化,扫描策略优化
三、完善持久化框架,充分考虑可扩展性
四、优化设备过滤器,加速设备识别,充分利用缓存
五、多线程优化,避免数据不一致的问题
六、性能优化,减少GC,尽量简化流程,尽量复用
七、采用事件总线,减少耦合
八、可考虑开发一个蓝牙广播解析器,定义好广播包协议格式xml后,由该解析器自动生成对应的广播包类和parser类。

框架github地址:https://github.com/dingjikerbo/BluetoothCommon

2 0
原创粉丝点击