分布式软总线跨设备任务迁移:可靠状态同步与回滚设计
·
分布式软总线跨设备任务迁移:可靠状态同步与回滚设计
前言
分布式软总线(Distributed Soft Bus)是鸿蒙"超级终端"能力的底座,让手机、平板、车机之间可以无缝迁移任务、共享状态。但"迁移"默认只是一次性快照——把当前页面/数据推到对端就结束。之后两端各自演进,一旦网络抖动或设备掉线,状态就会分叉。本文给出一个可落地的"版本号 + 操作日志 + 协调者"同步模型,并附带回滚策略。
问题描述
典型痛点:
- A 设备改了状态,B 设备没收到(网络抖动丢包),两者不一致。
- A、B 同时改了同一字段,谁覆盖谁?没有协调者就乱。
- 迁移过程中对端崩溃,A 端已经"认为成功",实际状态残缺。
- 想撤销上一步操作,发现没存历史快照,无法回滚。
根因:publish/subscribe 是发后不管的,没有 ack、没有版本、没有冲突解决。
细节解析
可靠同步四要素:
- 版本号:每条状态带
version,每次变更自增。对端收到低版本直接丢弃,避免旧数据覆盖新数据。 - 传操作而非传全量:发"增量操作日志(Op Log)"而不是整坨状态。带宽小、天然可重放、可回滚。
- 协调者(主设备):多设备场景必须有唯一主设备裁决冲突(最后写入胜出 / 指定主)。无主则多主互相覆盖。
- ack + 重发:发布端维护"已确认"集合,断线重连后补发未确认 Op;对端按
version去重。
回滚:保留最近 N 个快照,异常时用上一个成功快照 restore(version)。
示例代码
定义带版本的状态与操作:
// state.ets
export interface SyncState {
data: Record<string, Object>;
version: number;
devId: string;
}
export interface Op {
version: number;
devId: string;
type: 'set' | 'delete';
key: string;
value?: Object;
}
发布端:发操作日志 + 维护确认:
import { distributedSoftBus } from '@kit.DistributedSoftBus';
const confirmed = new Set<number>();
export function sendOp(op: Op) {
// 通过软总线发布,对端重放该操作
distributedSoftBus.publish('topic_state_sync', JSON.stringify(op));
// 简单 ack 机制:订阅回执
// 未在超时内确认则重发
scheduleResend(op);
}
function applyOp(state: SyncState, op: Op): SyncState {
if (op.version <= state.version) return state; // 丢弃过期操作
const next = { ...state.data };
if (op.type === 'set') next[op.key] = op.value!;
else delete next[op.key];
return { data: next, version: op.version, devId: op.devId };
}
接收端:按版本重放 + 去重:
distributedSoftBus.subscribe('topic_state_sync', (data: string) => {
const op: Op = JSON.parse(data);
if (localState.version >= op.version) return; // 已应用或过期
localState = applyOp(localState, op);
sendAck(op.version); // 回执,让发布端移除重发
});
回滚:
const snapshots: SyncState[] = []; // 最近 N 个
function snapshot() { snapshots.push({ ...localState }); if (snapshots.length > 10) snapshots.shift(); }
function rollback() { localState = snapshots[snapshots.length - 2] ?? localState; }
总结
- 迁移只是快照,持续同步要自己建机制。
- 传操作日志 > 传全量;版本号解决覆盖;协调者解决冲突;ack 解决丢包。
- 回滚靠"保留最近快照",别只存当前态。
- 验证:A 改→断网→B 改→恢复网络,应能在协调者裁决下合并或回滚到一致点,而非分叉。
更多推荐




所有评论(0)