You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

refCount维持BLE连接出错后仍保持连接、重放错误的解决方法咨询

问题根源

当前使用的replay+refCount组合存在固有特性:上游BLE连接流发送onError终止事件后,replay内部缓存会永久持有该错误事件,所有后续新订阅都会直接收到重放的错误;同时refCount接收到终止事件后不会自动重置共享状态,因此会出现连接被持续持有的假象。


方案一:出错后立即断开连接(对应第一个需求)

核心逻辑是错误发生时主动终止当前共享流,直接释放上游连接,同时重置refCount的共享状态,下次新订阅时会自动重建连接。

修改后代码:

bleDevice
    .establishConnection(false)
    // 捕获上游错误,转成onComplete事件终止当前流,触发refCount释放连接
    .onErrorResumeNext(Observable.empty())
    .replay(1)
    .refCount(1, 5, TimeUnit.MINUTES)
    // 可选:如果需要订阅侧感知到连接错误,可以加上下行注释的代码,自定义异常抛出
    // .switchIfEmpty(Observable.error(new BLEConnectionBrokenException()))

该方案适合不需要自动重连的场景,错误发生后5分钟保活逻辑也会同步终止,不会再持有无效连接。


方案二:禁止replay重放错误(对应第二个需求)

核心逻辑是将错误事件转换为普通事件处理,避免replay将错误识别为终止事件进行缓存。

如果需要当前订阅者能收到错误、新订阅者不重放历史错误,代码如下:

bleDevice
    .establishConnection(false)
    // 将所有事件包装为普通Notification对象,避免replay识别到终止事件
    .materialize()
    .replay(1)
    .refCount(1, 5, TimeUnit.MINUTES)
    // 下游将Notification还原为正常事件传递给订阅者
    .dematerialize(Function.identity())

如果需要完全不缓存错误,只重放正常的连接数据,调整代码增加过滤逻辑即可:

bleDevice
    .establishConnection(false)
    .materialize()
    // 仅允许正常的业务数据进入缓存,错误/完成事件直接丢弃不缓存
    .filter(Notification::isOnNext)
    .replay(1)
    .refCount(1, 5, TimeUnit.MINUTES)
    .dematerialize(Function.identity())

该方案适合需要保留5分钟保活逻辑,仅需要屏蔽错误重放的场景。


内容的提问来源于stack exchange,提问作者RefuX

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.20 03:45:04