2020征文-手机 快速搭建一款鸿蒙分布式分歧终端机原型

开发 分布式
文章由鸿蒙社区产出,想要了解更多内容请前往:51CTO和华为官方战略合作共建的鸿蒙技术社区https://harmonyos.51cto.com/#zz

[[360501]]

 想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com/#zz

子曾经曰过,有鸿蒙,一切皆有可能。

世界上之所以战火不断

冲突加剧

根源就是

分歧得不到公正的裁决

我们小时候都玩过一种游戏

锤子剪刀布

其实那是一种解决分歧

最原始最有效的方法

可是为什么我们长大了以后

就不用这种方法了呢?

因为他有两个弊端

一个是出手的快慢

另一个就是临时变换手型

分歧终端机的问世

一举解决了这个难题

[[360502]]

那么,问题来了

这么好的一个跨时代的产品

为什么没有得到推广呢?

因为它有两个弊端:

一个是不方便携带

另一个是……贵(划掉)……不开源

开源的鸿蒙分布式分歧终端机的问世

一举解决了这个问题

[[360503]]

那么,构建这样一款鸿蒙分布式分歧终端机**原型**,需要多长时间呢?

10分钟?

不,

大概要……

一个周末吧。

具体需要三个步骤:

第一步,先把家里的娃哄好

第二步,打开电脑写 Bug(划掉)代码

第三步,调试,如果有问题,重复第二步

万事开头难,第一步永远是最难的。

处理好了第一步以后,后两步就简单了,我们来具体分析一下鸿蒙分布式分歧终端机原型的设计原理。

# 鸿蒙分布式分歧终端机原型的设计

## 首先,需求分析

1). 可以**输入**各自的决策

2). 由中立第三方进行**裁决**

3). 可以**查看**最终的裁决**结果**

## 其次,模块划分。

根据需求,利用鸿蒙的分布式设计思想,我们将分歧终端机分为两个核心模块:

1). 分歧终端机的交互模块,简称FA,用于输入决策和查看结果

2). 分歧终端机的计算模块,简称PA,作为中立第三方,做出最终裁决


## 再次,流程。

假定有A和B两人发生分歧,需要解决分歧,那么分歧解决的一个典型流程可以这样子:

1). A 启动分歧终端机的交互模块(FA-A)

2). B 启动分歧终端机的交互模块(FA-B)

3). A 和 B 都连接到同一个分歧终端机计算模块,假定是计算模块A(PA-A)

4). A 和 B 在各自的分歧终端机的交互模块上输入他和她的决策(INPUT-A,INPUT-B)

5). 分歧终端机的计算模块自动根据 A 和 B 的输入,计算出结果:RESULT

6). A 和 B 在各自分歧终端机的交互模块上查看结果RESULT,假如B对结果不满意,可以进行再次裁决,直到她满意为止。


## 再次,详细设计。

### 1. 分歧终端机交互模块(FA)

交互模块需要向使用者提供输入接口和显示界面,所以使用的是鸿蒙的FA,也就是 Feature Ability。

FA 也叫Page Ability,而一个Page可以有多个Ability Slice(能力切片),也就是子页面:


根据决策过程的不同阶段,我们利用Ability Slice设计3个子页面,分别是:

* 1). 初始准备页面,HomeSlice,用于连接分歧终端机计算模块(PA)

这里,我们会需要用到鸿蒙分布式软总线的

a). 设备自动发现能力

对于在同一个网络下的鸿蒙设备,在满足条件的情况下,可以自动互相发现,不需要调用网络接口(udp/tcp等),也不需要针对不同的网络状况(wifi/蓝牙/nfc等) 做不同的实现。

b). 设备直连能力

通过connectAbility接口,可以直接连接需要连接的计算模块,不要知道其所在设备的实际网络情况。

* 2). 等待页面,WaitingSlice,先加入分歧解决的人,需要在这个页面上等待其他人加入。

当发现所有人都已经加入后,就自动进入下一个页面,也就是“分歧决策页面”。


* 3). 决策页面,GameSlice,参与分歧解决的人在这个页面上输入自己的决策,并查看最终的裁决结果。


本模块的技术要点:

1). 子页面之间的切换:使用present方法

2). 决策结果的刷新:可以用计时器来轮询结果,并刷新。

注意

在计时器中刷新UI时,相关代码需要运行在UI线程上,可以使用EventRunner,参考代码:

  1. public void runInMainThread(Runnable task){ 
  2.  
  3. EventRunner runner = EventRunner.getMainEventRunner(); 
  4.  
  5. EventHandler handler = new EventHandler(runner); 
  6.  
  7. handler.postTask(task); 
  8.  
  9.  
  10. private void startGameLoop(){ 
  11.  
  12. if(gameTimer == null){ 
  13.  
  14. gameTimer = new IntervalTimer(1000, 1000) { 
  15.  
  16. @Override 
  17.  
  18. public void onInterval(long l) { 
  19.  
  20. runInMainThread(new Runnable() { 
  21.  
  22. @Override 
  23.  
  24. public void run() { 
  25.  
  26. onLoop(l); 
  27.  
  28.  
  29. }); 
  30.  
  31.  
  32. @Override 
  33.  
  34. public void onFinish() { 
  35.  
  36. gameTimer.schedule(); 
  37.  
  38.  
  39. }; 
  40.  
  41. gameTimer.schedule(); 
  42.  
  43.  
  44.  
  45. private void stopGameLoop(){ 
  46.  
  47. if(gameTimer != null){ 
  48.  
  49. gameTimer.cancel(); 
  50.  
  51. gameTimer = null
  52.  
  53.  

 参考文档

1). Page Ability 开发指南

https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ability-page-concept-0000000000033573

2). JAVA UI 框架开发指南

https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ui-java-overview-0000000000500404

### 2. 分歧终端机核心计算模块(PA)

计算模块的核心任务是进行数据处理,而不需要显示,所以用到的是鸿蒙的PA,也就是Particle Ability。

计算模块需要实现的功能是:

a). 收集来自交互模块的决策输入

b). 根据各自的决策来做出最终裁决

决策过程,基本上就是一个判断 a > b 的过程,就不赘述了。

技术要点

1). 连接PA时,使用connectAbility

2). 可能会有多线程数据同步的问题

3). 要进行跨设备操作,需要在代码里,手动申请必要的权限

在项目模块的 config.json:

  1. "reqPermissions": [ 
  2.  
  3.  
  4. "name""ohos.permission.DISTRIBUTED_DATASYNC"  
  5. }, 
  6.  
  7.  
  8. "name""ohos.permission.DISTRIBUTED_DEVICE_STATE_CHANGE"  
  9. }, 
  10.  
  11.  
  12. "name""ohos.permission.GET_DISTRIBUTED_DEVICE_INFO"  
  13. }, 
  14.  
  15.  
  16. "name""ohos.permission.GET_BUNDLE_INFO"  
  17. }, 
  18.  
  19.  
  20. "name""ohos.permission.servicebus.ACCESS_SERVICE"  
  21. }, 
  22.  
  23.  
  24. "name""ohos.permission.servicebus.DISTRIBUTED_DEVICE_STATE_CHANGE"  
  25. }, 
  26.  
  27.  
  28. "name""ohos.permission.servicebus.GET_BUNDLE_INFO"  
  29.  
  30. ], 

 在MainAbility启动时申请权限:

  1. public class MainAbility extends Ability { 
  2.  
  3. private static final String TAG = MainAbility.class.getSimpleName(); 
  4.  
  5. @Override 
  6.  
  7. public void onStart(Intent intent) { 
  8.  
  9. super.onStart(intent); 
  10.  
  11. super.setMainRoute(HomeSlice.class.getName()); 
  12.  
  13. GameClient.getInstance().init(); 
  14.  
  15. requestPermissionsFromUser( 
  16.  
  17. new String[]{ 
  18.  
  19. "ohos.permission.DISTRIBUTED_DATASYNC"
  20.  
  21. "ohos.permission.GET_DISTRIBUTED_DEVICE_INFO"
  22.  
  23. "ohos.permission.servicebus.ACCESS_SERVICE" 
  24.  
  25. }, 0); 
  26.  
  27.  

 参考文档

1). Service Ability 开发指南

https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ability-service-concept-0000000000044457

2). 分布式任务调度

https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ability-distributed-overview-0000001050419345

### 3. 交互模块与计算模块的数据通信

既然是两个模块之间要做交互,那么必然就涉及到数据通信。

数据通信过程中,除了调用相关的通信接口以外,另一个很重要的点就是要对数据进行封包和解包。

整个通信过程,是通过鸿蒙分布式软总线来完成的。

我们当然可以利用软总线提供的接口来实现通信过程,并自己定义数据结构、以及封包和解包的方法。

但是,这样就没办法在10分钟内完成了。

幸运的是,鸿蒙提供了一个很方便的工具,IDL(鸿蒙接口定义语言),来帮我们完成这个让人头秃的工作。

> IDL官方文档

> https://developer.harmonyos.com/cn/docs/documentation/doc-references/idl-overview-0000001050762835

利用IDL工具,只需要3步,就可以实现数据通信功能:

1). 在IDL文件中定义好接口,方法,方法的输入输出参数

2). 利用DevEco Studio工具将IDL文件转换为代码

3). 实现具体的业务逻辑

定义好接口以后,我们就可以像调用本地方法一样,调用远程方法了。

IDL 代码示例:

  1. // IGameServiceInterface.idl 
  2.  
  3. // Declare any non-default types here with sequenceable or interface statements 
  4.  
  5. // 申明一个可序列化的结构,具体的定义在Java中编写,详情参看IDL文档 
  6.  
  7. sequenceable com.blackshadowgame.rps.GameResultData; 
  8.  
  9. interface com.blackshadowgame.rps.IGameServiceInterface { 
  10.  
  11. int echo([inint a); 
  12.  
  13. // 加入游戏 
  14.  
  15. int joinGame([in] String playerId); 
  16.  
  17. // 与AI对决 
  18.  
  19. int playWithAI([inint pid); 
  20.  
  21. // 获取当前局的对手列表 
  22.  
  23. int[] getPlayers([inint pid); 
  24.  
  25. // 出拳 
  26.  
  27. int sendInput([inint pid, [inint inputCode); 
  28.  
  29. // 查询结果 
  30.  
  31. GameResultData queryGameResult([inint pid); 
  32.  
  33. // 离开游戏 
  34.  
  35. int leaveGame([inint pid); 
  36.  
  37. int nextGame([inint pid); 
  38.  

 ### 4. 组装和测试

现在各个模块都准备好了,将 FA/PA/IDL 组装起来,进行

联......

调......

测......

试......

[[360511]]

如果你足够幸运的话,可能10分钟就调试完毕,如果不够幸运,经过无数次测试和修改,最终也能调试出没有明显bug的版本进行体验。


这样,一款鸿蒙分布式分歧终端机原型,就完成了!

### 6. 关于界面美化

你说需要对界面进行美化?

## Pro 版本

鸿蒙分布式分歧终端机还可以升级到Pro版,增加更多“Profession”的功能。利用鸿蒙的分布式能力,这些都可以很轻松实现,例如:

1). AI切磋:供无聊人士进行切磋

2). 围观:供吃瓜群众围观分歧决策过程

3). 多人切磋:超过2人以上切磋的玩法

4). 邀请/强制切磋:邀请他人参与切磋的玩法

5). 任意设备切磋:除了手机,支持其他设备作为输入进行切磋,例如手表等

6). 大屏协同切磋:切磋玩家在自己的设备上输入,然后在大屏上显示结果

## 开源代码

本项目代码已经上传到gitee,供大家参考一下。

> https://gitee.com/devonzhang/rock-paper-scissors


## 参考文献

完成本项目所需要的技能点,都可以通过在鸿蒙OS开发者官网上找到学习资料。

1). 鸿蒙OS应用开发指南

https://developer.harmonyos.com/cn/docs/documentation/doc-guides/document-outline-0000001064589184

2). Ability 开发指南

https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ability-ability-overview-0000000000029852

3). Page Ability 开发指南

https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ability-page-concept-0000000000033573

4). Service Ability 开发指南

https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ability-service-concept-0000000000044457

5). 分布式任务调度

https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ability-distributed-overview-0000001050419345

6). JAVA UI 框架开发指南

https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ui-java-overview-0000000000500404

7). 鸿蒙OS IDL接口使用规范

https://developer.harmonyos.com/cn/docs/documentation/doc-references/idl-overview-0000001050762835

## 最后

本项目代码仅供学习之用,请勿直接使用到生产环境中,如果出现bug,概不负责~

# 最后的最后

既然你已经看到这里,我是阿斌,一个全栈游戏开发,欢迎

1. 订阅我的鸿蒙学习专栏:《跟阿斌一起学鸿蒙》 https://harmonyos.51cto.com/column/25

2. 关注我的个人公众号:耿直的IT男阿斌

3. 查看我的技术博客:https://xmanyou.com/

©著作权归作者和HarmonyOS技术社区共同所有,如需转载,请注明出处,否则将追究法律责任

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com/#zz

 

责任编辑:jianghua 来源: 鸿蒙社区
相关推荐

2021-11-08 19:25:37

Go生成系统

2023-12-14 09:17:30

Jami开源

2017-04-06 15:15:02

多场景分布式发号器

2019-12-18 10:24:10

数据库PostgreSQL Oracle

2018-06-05 14:21:33

NewSQLMySQLRadonDB

2021-04-27 10:17:42

数据库工具技术

2015-06-30 12:49:27

HBaseNoSQL分布式

2013-11-18 14:00:09

2017-03-06 11:02:59

产品软件Power Desig

2020-12-28 10:15:18

鸿蒙HarmonyOSListContain

2023-04-26 08:01:09

分布式编译系统

2017-08-10 10:17:32

Hadoop分布式搭建

2021-01-27 13:16:39

ScreenLinux命令

2021-02-16 10:58:50

ScreenLinux命令

2020-06-01 16:45:44

Linux终端Terminus

2009-08-20 20:38:10

终端机ATM黑客攻击

2013-11-14 14:02:57

2024-06-12 09:06:48

2024-11-28 10:56:55

2019-10-10 09:16:34

Zookeeper架构分布式
点赞
收藏

51CTO技术栈公众号