坦克大战Netty网络联机版项目笔记

项目地址:https://github.com/2017403603/TankGame.git

一、单工,半双工,全双工区别

1. 单工

​ 数据只在一个方向上传输,不能实现双方通信。

2. 半双工

​ 允许数据在两个方向上传输,但是同一时间数据只能在一个方向上传输,其实际上是切换的单工。

3. 全双工

​ 允许数据在两个方向上同时传输。

二、项目中遇到的问题

1.联机坦克如何显示在同一区域?

​ 在服务器端定义一个HashMap,每次有玩家连接进服务器的时候,将玩家的id和通信channel一起存进HashMap中,以便在需要进行坦克之间通信的时候,能够及时找到相应坦克的channel进行通信,每次玩家移动坦克,将会把坦克的位置信息发送给服务器,服务器接收到的信息,依次遍历HashMap中所有的channel,将位置信息发送给所有玩家,实现联机。

2. 服务器中的channel异常了怎么办?

​ 如果服务器中的channel出现了异常,如客户端连接突然中断,则将服务器中HashMap的对应channel移除,并且close这个channel,以免造成服务器异常

​ 客户端优雅退出连接:发出特定消息,服务器端收到,将HashMap的对应channel移除,并且close。

3. 自定义传递消息协议

​ 每个坦克都需要和服务器端进行通信,通信所传递的消息我们封装成一个消息类,类的属性有xy坐标,方向、速度、分组等,消息类自定义了一些方法用于消息传递,如序列化、反序列化等;自定义协议内容:

  • 魔数,用来在第一时间判定是否是无效数据包
  • 版本号,可以支持协议的升级
  • 序列化算法,消息正文到底采用哪种序列化反序列化方式,可以由此扩展,例如:json、protobuf、hessian、jdk
  • 指令类型,是登录、注册、单聊、群聊… 跟业务相关
  • 请求序号,为了双工通信,提供异步能力
  • 正文长度
  • 消息正文

​ 每个玩家坦克都有一个独一无二的id,这个id由服务器端生成,用于表示不同玩家。

4. 接收到Tankjoinmsg消息类的逻辑处理(服务器保存所有状态)

  1. 是不是自己?
  2. 列表是不是有了?
  3. 发自己的一个Tankjoinmsg消息类

5. 如何实现整个界面事件联机

​ 例如,玩家坦克加入是一个事件,我们把它包装成一个协议类,同样玩家坦克移动、射击、爆炸、暂停游戏也是一个事件,也需要包装成一个协议类用于玩家坦克之间消息传递,我们抽象出一个父类Msg,之后所有的消息协议类都继承Msg,服务器端和客户端在每次接收到消息协议类时都会判断消息类型,并做出对应消息的后续处理;可以把对应消息的后续处理也封装到消息协议类之中,这样无论接收到什么消息,都只要消息自己处理,省去了判断消息类型的步骤。

6. 所有消息类型

  • TankJoinMsg类:当有新的玩家坦克加入游戏(服务器)时,向服务器端发送一个TankJoinMsg消息类,服务器端收到后立即将消息类转发给其他玩家,告诉其他玩家有新的坦克玩家加入,其他玩家收到消息后会判断本身客户端是否已经记录了这个坦克消息,如果没有记录,则发送自身的TankJoinMsg消息类(类的属性有xy坐标,方向、速度、分组等),如果已经记录,则说明这个坦克信息之前就有了,不用处理(每个客户端里面都有个list集合用于存储在线的玩家坦克信息,根据集合里面的内容画出对应玩家坦克);达到玩家坦克加入的画面同步。
  • TankDirChangedMsg类:当有玩家改变坦克方向时,向服务器端发送一个TankDirChangedMsg消息类,服务器端收到后立即将消息类转发给其他玩家,告诉其他玩家此坦克方向已经改变,所有客户端根据信息重新绘制坦克方向。(类的内容有当前xy坐标、更改后的方向、更改的玩家id)
  • **TankStopMsg/TankStartMovingMsg类:**当有玩家按下/松开移动键时,向服务器端发送一个TankStopMsg/TankStartMovingMsg消息类,服务器端收到后立即将消息类转发给其他玩家,告诉其他玩家此坦克移动/停止状态已经发送改变,所有客户端根据状态量重新绘制对应坦克移动/停止。(xy、dir、id)
  • BulletNewMsg类:当有玩家按下发射键时,该玩家向服务器端发送一个BulletNewMsg消息类,类的内容有子弹id、发射子弹的玩家id、要发射子弹的xy位置、子弹分组和子弹方向等,服务器端收到后立即将消息类转发给其他玩家,告诉其他玩家xy位置出现了一颗子弹,所有客户端收到子弹放入list并且绘制。
  • TankDieMsg、TankblastMsg、BulletdieMsg类…:这几个消息由服务器发送,服务器端控制着整局游戏的状态,子弹增加的时候公共资源部分也会修改增加,当公共资源部分检测到爆炸或者坦克消亡时,会给所有坦克玩家发送TankDieMsg、TankblastMsg、BulletdieMsg消息类,以此来同步画面和资源状态。
  • 道具类、城墙类特效消息类:原理与上面大同小异。
  • 相同点
    1. 都是由玩家发出消息类给服务器,服务器端接收到消息类马上转发给其他玩家,以此来同步玩家状态。
    2. 服务器端控制公共资源状态,当检测到公共资源发生变化,如城墙爆炸、坦克爆炸、子弹消失/爆炸等,立即发送消息给所有坦克玩家,以此来同步游戏状态。

7. 数据流轨迹

  1. 具体消息类继承抽象类Msg,实现处理、序列化、反序列化方法。
  2. 自定义协议,经过encoder编码,将具体消息类序列化变成字节数组,以便于发送,加上协议头之后通过channel发送字节数组。
  3. decoder译码,解析协议头,获取到正确的字节数组,根据解析到的消息类型,反序列化字节数组,以此来获取到想要的消息类信息。
  4. 接收到正确的消息类之后,调用消息类的处理方法进一步处理。

8. 整个游戏后端架构

​ 整个后端架构可以看成是一个AFS架构,服务器端看成master节点,客户端看成worker节点,服务器端保存整局游戏的所有状态(如果整局游戏的状态在客户端,很有可能会被外挂修改状态,达到作弊的效果),当数据状态发生改变的时候,将状态发生改变的那一部分数据同步给所有客户端,已达到实时联机的效果;每次当一个游戏玩家发出一个事件,都会通过channel先发送到服务器端,然后通过服务器端对该游戏其他玩家的channel发送事件信息,以便其他玩家能够同步事件。

​ 为什么不用NFS架构?

​ NFS架构设计初衷是为了更好的容错,便于数据恢复;而AFS设计初衷是为了更多的用户并发使用,保证更好的实时性。

9. 坦克大战游戏服务器理解

​ 游戏的服务器有很多种,坦克大战使用的服务器是最简单的一种方式,简单且资源消耗少,即收到消息就直接全部转发给其他玩家。

10. 为什么要禁用Nagle算法

​ TCP为了实现增加传输效率会使用Nagle算法,而Nagle算法在游戏服务器领域是被禁用的;原因是Nagle算法如果传输的协议包过小,会积累好几个数据包一起发送,而在游戏中会造成信息的延迟,导致数据不同步。

11. 整个游戏服务器整体划分

  • 整局游戏的全部资源状态由服务器端保存,游戏的资源分为公共资源和玩家资源两部分。
  • 公共资源为电脑(人机)敌人坦克和城墙、道具等,由服务器端控制并检测其状态,当状态发生改变发送对应消息类给所有玩家,同步服务器和所有玩家的画面资源数据。
  • 玩家资源部分由玩家自己控制,产生的动作包装成消息类发送给服务器,服务器接收到后马上转发给其他玩家,之后服务器端进行接收到的消息逻辑处理,处理结果也转发给所有玩家。
  • 实现公共资源和玩家资源的数据信息同步。

坦克大战Netty网络联机版项目笔记相关推荐

  1. 基于Netty的联机版坦克大战

    基于Netty的联机版坦克大战 项目介绍 项目github地址:基于Netty的联机版坦克大战 该项目实现了联机版坦克大战,项目包括客户端与服务端 项目使用技术: 使用Netty实现客户端和服务端之间 ...

  2. java怎么给坦克上图片_Java坦克大战 (七) 之图片版

    在此小易将坦克大战这个项目分为几个版本,以此对J2SE的知识进行回顾和总结,希望这样也能给刚学完J2SE的小伙伴们一点启示! 坦克大战效果图: 坦克大战V0.7图片版实现功能: 1.将方向定义为一个E ...

  3. Java坦克大战 (七) 之图片版

    本文来自:小易博客专栏.转载请注明出处:http://blog.csdn.net/oldinaction 在此小易将坦克大战这个项目分为几个版本,以此对J2SE的知识进行回顾和总结,希望这样也能给刚学 ...

  4. 坦克大战进阶第三版:防止重叠、击杀记录、存盘退出、背景音乐等

    坦克大战进阶第三版:防止重叠.击杀记录.存盘退出.背景音乐等 1. 坦克大战0.5版 1.1 功能进阶: 增加功能[HspTankGame05java] 防止敌人坦克重叠运动[思路->走代码] ...

  5. Netty网络编程聊天项目

                                     Netty网络编程聊天项目 后端编写 导入依赖    <dependencies><dependency>&l ...

  6. ava联网3D坦克大战(网络编程)2020

    .游戏效果 Java网络编程联机3D坦克大战 在这里插入图片描述 在这里插入图片描述 二.游戏涉及知识 服务器端运用了 IO.线程.网络.面向对象.异常 的内容, 客户端使用 unity3d引擎进行开 ...

  7. 【Unity】超级坦克大战(一)搭建项目、导入框架、前期开发准备

    更新日期:2020年7月9日. 项目源码:在终章发布 免责声明:超级坦克大战使用的图片.音频等所有素材均有可能来自互联网,本专栏所有文章仅做学习和教程目的,不会将任何素材用于任何商业用途. 索引 [系 ...

  8. 基于Eclipse+GUI+Swing开发得网络版坦克大战多人联机版本设计和实现

    总体功能图: 总体流程图:     图3  启动测试图     图4  建立主机按钮测试图 图5  连接主机按钮测试图 (3)点击帮助按钮,成功在页面上显示游戏的方法.如图6所示.     图6  帮 ...

  9. java用drawline画血条,Java小项目之坦克大战单机1.0版

    单机1.0版包括6个class文件: TankClient.java : 主要执行部分,项目的大管家 Tank.java : 实现Tank类,模拟坦克的运动 Missile.java : 实现Miss ...

  10. qt4.8.5键盘发送消息_单机游戏下载:雨中冒险2 网络联机版 v1.0.0.5|容量2.7GB|官方简体中文|支持键盘.鼠标.手柄|内置网络联机教程...

    " 雨中冒险2" 游戏介绍 浴血奋战杀出暴戾的怪物重围,在混乱的外星球上逃过劫难.可孤军奋战,也可与好友并肩作战.以出人意料的方式合成战利品,同时精通每个角色,直至您自己成为初次迫 ...

最新文章

  1. 函数语法:JS获取浏览器窗口大小 获取屏幕,浏览器,网页高度宽度(转载)...
  2. python matplotlib散点图-Matplotlib scatter绘制散点图的方法实现
  3. 最优化评分法c语言,最优化方法及其实现(Optimization-Algorithm)C语言
  4. django安装mysql驱动_django安装mysql驱动
  5. Struts2与Spring、Hibernate三者整合的过程示例
  6. 网络知识:各种缓存核心知识整理,值得收藏!
  7. Android 固定式底部上滑抽屉view
  8. 不同技术团队的配合问题及DevOps
  9. 华为鸿蒙OS首批升级机型名单曝光 荣耀老机型或在第二、三批名单
  10. python预测股票价格_python用线性回归预测股票价格
  11. Android中service的生命周期
  12. wordpress and theme
  13. 机器学习实战pdf原文内容分享
  14. 旁路电容、滤波电容、去耦电容的作用与应用原理详解
  15. win7变成xp风格了怎么改回_win7怎么变成xp界面|win7系统变成xp界面主题的方法
  16. Kali 实现ARP断网攻击_arp断网攻击_arp欺骗
  17. 普罗米修斯监控mysql与邮件告警
  18. 「CodePlus 2017 11 月赛」大吉大利,晚上吃鸡!
  19. VMware 15 安装 macOS High Sierra 10.13 图文教程
  20. 健身服务公司iFIT赴美上市,64亿美元估值中藏着“喜”与“忧”?

热门文章

  1. java中小数点位数_Java中限制小数位数问题
  2. 检察院批准逮捕洪磊,铁杆分子不买帐
  3. dacom蓝牙耳机怎么重置_无线蓝牙耳机 常见八大故障解决办法
  4. SpringBoot exclude的使用
  5. java 生成pdf文件_Java 生成PDF文档的示例代码
  6. ELEMENT UI中关于上传图片el-upload控件删除(同时删除后台图片信息)
  7. 计算机学院学位证发放仪式,新征程,新梦想--计算机学院举办2019届毕业生学位授予仪式...
  8. Hadoop报错Permissions incorrectly set for dir /tmp/hadoop-LeiHanhan/nm-local-dir/filecache, should be
  9. Kotlin基础知识5
  10. 经典Java练习题 Mars Rover