模拟器是在单进程里面模拟两个 zone,内置两个 ood,每个 ood 两台 device 设备,可以用以开发和测试常见的一些用例。
- zone-simulator 默认从助记词,通过 bip 协议衍生所有的 people、device 信息,所以同一套助记词每次生成相同的 zone 配置信息
- 首次启动后默认创建一个随机助记词,保存在{cyfs-root}/etc/zone-simulator/mnemonic;以后每次启动后都会加载此配置,如果需要创建新的 zone desc 信息,那么删除此配置文件即可
- debug 版本从助记词衍生密钥执行速度会比较慢,一般需要一到两分钟才会执行完毕
zone 信息包含下面
- 两个 people desc 信息,分别代表两个 zone
- 两个 ood desc 信息,分别代表两个 zone 的 ood
- 四个 device desc 信息,分别代表每个 zone 里面的两台 device,和所在 zone 的 ood 组成一个独立的 zone
zone-simulator 启动后,会把上述信息写入{cyfs-root}/etc/zone-simulator/desc_list 目录,这个和助记词一一对应,同一套助记词生成的 desc 信息列表每次启动都是相同的,开发和测试可以直接依赖这些信息
比如对于助记词
million used drastic castle during top category wood street visa steak bachelor
生成的 desc list 如下
zone1 as follows:
people:5r4MYfFFQetBPDyeuBuDxPT7zowk9497SbpMQsZK2G19
ood:5aSixgLq9LVWbPByjRYgyjGicXtCN5S1nF1DMKZygLRE
device1:5aSixgPFg7R48VSo2b9PXcSHofK3TUFUcHnHbtmB7fJr
device2:5aSixgRaonSm1qWeCh8kNNrPGaB6pbETsqoN4Zb5Ev3H
zone2 as follows:
people:5r4MYfFGppKJXEjLvsgbKsibmTVLFZhL5cuZdEcXSr68
ood:5aSixgM12wHBfJBW1Q9n4xv1c5cu5g8hSxbrkhAQoojq
device1:5aSixgPdH5stj9pHrRVGXPNKiyrPsy8932BEr3zwFhXF
device2:5aSixgRx45jDU4Fg4ijYo3Yfo6RajtKSHgnGCVJUnk65
上述 device_id 和 people_id 信息,可以直接作为 router 等接口的 target 使用,用来和对应的协议栈进行交互
比如向 ood1 作为目标 put_object:
const ood1 = DeviceId.from_base_58('5aSixgLq9LVWbPByjRYgyjGicXtCN5S1nF1DMKZygLRE').unwrap();
const target = ood1.object_id;
stack.put_object({
...,
target
})
可以直接使用 zone1 的 people_id 作为 target:
const people1 = PeopleId.from_base_58('5r4MYfFFQetBPDyeuBuDxPT7zowk9497SbpMQsZK2G19').unwrap();
const target = people1.object_id;
stack.put_object({
...,
target
})
两个 zone,每个 zone 里面包含一个 ood+两个 device,所以一共存在六个协议栈,为了方便外部 sdk 调用,所以使用了固定端口,分配如下
设备 | bdt-port | http-port | ws-port |
---|---|---|---|
zone1-ood1 | 20001 | 21000 | 21001 |
zone1-device1 | 20002 | 21002 | 21003 |
zone1-device2 | 20003 | 21004 | 21005 |
zone2-ood1 | 20010 | 21010 | 21011 |
zone2-device1 | 20011 | 21012 | 21013 |
zone2-device2 | 20012 | 21014 | 21015 |
其中 http-port 和 ws-port 可以作为本地 SharedObjectStack 的服务接口,直接使用 SharedObjectStack 的 open,传入对应的接口即可
比如想要使用 zone1-device2 的协议栈,可以使用下述代码 open:
const param = SharedObjectStackParam.new_with_ws_event_ports(21004, 21005).unwrap();
const stack = SharedObjectStack.open(param);
await stack.online();
上面两个 zone,可以模拟绝大部分 cyfs 里面的交互场景
- 同 zone 内两个设备交互,可以选择同一个 zone 的 device1 和 device2
- 同 zone 内 device 和 ood 交互,可以选择同一个 zone 的任意一个 device+ood
- 跨 zone 交互,zone1 和 zone2 内各选一个设备
- 模拟跨 zone server,使用 zone1 作为 client,zone2 作为 server,那么使用 zone1-device1+ood2 即可,ood2 上可以挂接 dec-service
在前面的章节中,我们都是使用真实环境进行测试,每次编码完都需要走一遍发布流程才能测试,这样会导致开发和测试效率很低。 现在,我们可以使用模拟器来大幅提升开发效率。
在项目根目录下的 tools/zone-simulator/mac 文件夹下,可以选择 aarch64 或者 x86_64 启动 zone-simulator 模拟器程序。
- 文件可能存在无执行权限问题,执行
chmod 775 zone-simulator
后运行即可。
在项目根目录下的 tool/zone-simulator/windows 文件夹下,启动 zone-simulator.exe 模拟器程序。
在项目根目录输入以下指令:
npm run dev
在 CYFS 浏览器中访问 http://localhost:8088,即可看到前端界面。
要运行 Service,我们需要使用 tsc 把项目中的 ts 文件编译成 js,在项目根目录下,打开新的终端,输入以下指令:
npx tsc
接着,把 src/common/objs/obj_proto_pb.js 文件拷贝到 deploy/src/common/objs/obj_proto_pb.js
最后,在根目录输入以下指令,开启模拟器模拟的两个 Zone:
npm run sim1
npm run sim2
需要注意的是,这两个指令分别对应两个终端执行。
打开 src/www/initialize.ts 文件,使用 useSimulator
方法的第 1 个参数来切换身份,例如,要使用 Zone1
的身份就设置为SimulatorZoneNo.FIRST
,使用 Zone1
的身份就设置为 SimulatorZoneNo.SECOND
。
现在,你已经可以在模拟器中快速的进行调试了。
推荐在任何可能出错的地方,打印日志,便于快速查找问题。
- 查看 CYFS 浏览器控制台的打印信息。
-
在模拟器环境,可以查看终端的打印信息,快速的发现错误。
-
在线上环境,可以分析 Service 的日志文件。
- mac: ~/Library/cyfs/log/app/<app_name>
- windows: C:\cyfs\log\app<app_name>
- linux: /cyfs/log/app/<app_name>
通过这个章节的学习,你已经掌握了在模拟器环境进行调试的知识和技巧,这会对你未来开发 Dec App 带来很大的便利。