在这里插入图片描述

网罗开发 (小红书、快手、视频号同名)

  大家好,我是 展菲,目前在上市企业从事人工智能项目研发管理工作,平时热衷于分享各种编程领域的软硬技能知识以及前沿技术,包括iOS、前端、Harmony OS、Java、Python等方向。在移动端开发、鸿蒙开发、物联网、嵌入式、云原生、开源等领域有深厚造诣。

图书作者:《ESP32-C3 物联网工程开发实战》
图书作者:《SwiftUI 入门,进阶与实战》
超级个体:COC上海社区主理人
特约讲师:大学讲师,谷歌亚马逊分享嘉宾
科技博主:华为HDE/HDG

我的博客内容涵盖广泛,主要分享技术教程、Bug解决方案、开发工具使用、前沿科技资讯、产品评测与使用体验。我特别关注云服务产品评测、AI 产品对比、开发板性能测试以及技术报告,同时也会提供产品优缺点分析、横向对比,并分享技术沙龙与行业大会的参会体验。我的目标是为读者提供有深度、有实用价值的技术洞察与分析。

展菲:您的前沿技术领航员
👋 大家好,我是展菲!
📱 全网搜索“展菲”,即可纵览我在各大平台的知识足迹。
每周定时推送干货满满的技术长文,从新兴框架的剖析到运维实战的复盘,助您技术进阶之路畅通无阻。


引言

当你完成了前面的架构升级:

Store(状态中心)
System(规则引擎)
Engine(调度层)
UI(多端展示)

你已经具备了“单设备内”的良好结构。

但一旦你真正进入 HarmonyOS(HarmonyOS)的核心能力区,你会遇到一个更本质的问题:

状态,怎么跨设备“实时流动”?

注意,这里不是:

同步一次数据

而是:

持续同步 + 多设备一致 + 接近实时

如果这个问题没解决,你前面所有“多端设计”,都会变成:

伪多端

所以我们只解决一件事:

如何让鸿蒙游戏在多设备之间“实时同步状态”?

一、多端同步,本质不是“传数据”

三件事:

1、状态必须“可序列化”
2、变更必须“可传播”
3、冲突必须“可解决”

如果只记一句话:

你同步的不是“状态本身”,而是“状态变化”

二、为什么“直接同步 Store”是错的?

很多人的第一反应是:

// 每秒同步一次
send(store)

看起来很合理,但实际问题巨大:

问题 1:性能爆炸

状态越来越大
频繁全量传输

问题 2:延迟明显

每次同步 = 一次完整快照

问题 3:冲突不可控

设备 A 改了
设备 B 也改了
谁覆盖谁?

所以结论很明确:

不能同步“整个 Store”

三、正确思路:同步“状态变化

我们把思路反过来:

不是同步结果
而是同步过程

示例

用户点击攻击:

store.enemyHp -= 10

传统同步:

同步 enemyHp = 90

正确同步:

发送一个事件:
{ type: "ATTACK", damage: 10 }

然后:

所有设备 → 执行同一个事件 → 得到同样结果

这一步的本质

状态 = Event 流的结果

四、核心架构:事件驱动同步

我们引入一个核心模块:

EventBus(事件总线)

结构图

        ┌──────────────┐
        │   EventBus   │
        └──────┬───────┘
               │
     ┌─────────┼─────────┐
     │         │         │
   设备 A    设备 B    设备 C
     │         │         │
   Engine    Engine    Engine
     │         │         │
    Store     Store     Store

流程

1、设备 A 产生事件
2、发送到 EventBus
3、广播到所有设备
4、每个设备执行同一事件

五、代码实现

1、定义事件

type GameEvent =
  | { type: 'ATTACK'; damage: number }
  | { type: 'TAKE_DAMAGE'; value: number }
  | { type: 'RESET' }

2、改造 System

class BattleSystem {

  handle(event: GameEvent, store: GameStore) {
    switch (event.type) {
      case 'ATTACK':
        store.enemyHp -= event.damage
        break

      case 'TAKE_DAMAGE':
        store.playerHp -= event.value
        break

      case 'RESET':
        store.reset()
        break
    }
  }

}

3、事件入口

function dispatch(event: GameEvent) {
  // 本地执行
  engine.handle(event, store)

  // 同步到其他设备
  sync(event)
}

4、远端接收

onRemoteEvent((event) => {
  engine.handle(event, store)
})

六、关键问题 1:如何保证“顺序一致”?

如果事件顺序不同:

A:ATTACK → RESET
B:RESET → ATTACK

结果完全不同。

解决方案:事件队列 + 时间戳

event = {
  type: 'ATTACK',
  damage: 10,
  timestamp: Date.now()
}

所有设备:

按时间排序执行

更严格方案:

引入“主设备”(Host)
统一分发顺序

七、关键问题 2:如何处理“冲突”?

典型场景:

设备 A:攻击
设备 B:同时攻击

方案 1:全部接受

两个事件都执行

结果:

伤害叠加

方案 2:主设备裁决

只有 Host 发出的事件有效

适用于:

竞技 / 强一致游戏

八、关键问题 3:如何处理“延迟”?

网络一定有延迟:

A 已经攻击
B 还没收到

解决方案:本地预测

dispatch(event) {
  // 先本地执行(立即反馈)
  engine.handle(event, store)

  // 再同步
  sync(event)
}

风险

如果远端结果不同 → 回滚

简化策略

允许轻微不一致
定期校准状态

九、关键问题 4:新设备加入怎么办?

新设备:

没有历史事件

解决方案:快照 + 事件

1、发送当前 Store 快照
2、继续接收事件流
sendSnapshot(store)
startSyncEvents()

十、最终完整模型

         ┌──────────────┐
         │   EventBus   │
         └──────┬───────┘
                │
        ┌───────┼────────┐
        │       │        │
     设备 A   设备 B   设备 C
        │       │        │
     Engine   Engine   Engine
        │       │        │
      Store   Store   Store

核心原则:

状态不直接同步
事件驱动一切

十一、你现在应该建立的认知

很多人一直在想:

怎么同步数据?

但正确问题是:

怎么同步“状态变化”?

从:

同步结果(错误)

升级为:

同步过程(正确)

十二、现实建议

如果你是刚开始做:

推荐策略:

1、先做单设备架构(Store + System)
2、再引入事件驱动
3、最后接入跨设备同步

不要一开始就:

分布式 + 多端 + 实时同步

否则:

直接复杂度爆炸

总结

鸿蒙游戏多端同步的本质是:

Event → 驱动状态变化
而不是 → 同步状态本身

核心三点:

状态可序列化
事件可传播
冲突可处理

结合整个系列,你已经可以把鸿蒙游戏抽象成一个完整模型:

System(规则)
   ↓
Event(变化)
   ↓
Store(状态)
   ↓
UI(多端渲染)

最终统一为:

鸿蒙游戏的“实时多端同步”,本质是一个“分布式事件驱动系统”。

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐