# 演示 #
![Avater](gitImage/show.gif)
# MOBA 服务器 编写思路 #
## 编写思路 ##
### 底层问题 ###
#### 同步问题 ####
在游戏领域,同步可以大致分为下面这两种,即:
1. 状态同步
2. 帧同步
状态同步是将游戏中大部分需要计算的逻辑都放在服务器上进行计算.
1. 优点是较为安全,可以防止游戏外挂的出现,如果有人打算制作外挂,必须先攻破游戏服务器
2. 缺点是性能问题,基于状态的同步,对服务器的性能是一个很大的挑战,且所有逻辑运算放到服务器上算,会导致游戏的延迟略高,对于实时性要求极高的游戏不适用。(即FPS,MOBA)
**我的理解**是帧同步是游戏内所有逻辑由客户端进行计算,只有在关键帧部分进行同步,所谓关键帧,类似于Flash中的说法,即在游戏中,某一帧是极为关键的,其他则只是作为过渡,举个例子,在一个联网的坦克大战游戏中,坦克发射炮弹的一瞬间就是关键帧,而坦克发射后,其运动轨迹并不需要服务器对其进行同步,而是由客户端进行计算,只有**坦克发射炮弹的那一瞬间**是需要同步的。
1. 优点:实时性强,服务端仅需要转发关键帧时的协议信息给各个客户端就可以了,对服务器的性能需求不算大
2. 缺点:安全性较弱,因为所有逻辑运算在客户端进行,容易被玩家更改本地数据从而制作游戏外挂
在本游戏中,因为是MOBA游戏,对游戏的实时性要求较高,故采用**帧同步**的方案。
#### 粘包、分包问题 ####
1.粘包产生原因
> 先说TCP:由于TCP协议本身的机制(面向连接的可靠地协议-三次握手机制)客户端与服务器会维持一个连接(Channel),数据在连接不断开的情况下,可以持续不断地将多个数据包发往服务器。
>
> 但是如果发送的网络数据包太小,那么他本身会启用Nagle算法(可配置是否启用)对较小的数据包进行合并(基于此,TCP的网络延迟要UDP的高些)然后再发送(超时或者包大小足够。
>
> 那么这样的话,服务器在接收到消息(数据流)的时候就无法区分哪些数据包是客户端自己分开发送的,这样产生了粘包;服务器在接收到数据库后,放到缓冲区中,如果消息没有被及时从缓存区取走,下次在取数据的时候可能就会出现一次取出多个数据包的情况,造成粘包现象(确切来讲,对于基于TCP协议的应用,不应用包来描述,而应用“流”来描述)。
>
> 个人认为服务器接收端产生的粘包应该与linux内核处理socket的方式 select轮询机制的线性扫描频度无关。
>
> 再说UDP:本身作为无连接的不可靠的传输协议(适合频繁发送较小的数据包),他不会对数据包进行合并发送(也就没有Nagle算法之说了),他直接是一端发送什么数据,直接就发出去了,既然他不会对数据合并,每一个数据包都是完整的(数据+UDP头+IP头等等发一次数据封装一次)也就没有粘包一说了。
2.分包产生原因
> 分包产生的原因:
>
> 可能是IP分片传输导致的,也可能是传输过程中丢失部分包导致出现的半包,还有可能就是一个包可能被分成了两次传输,在取数据的时候,先取到了一部分(还可能与接收的缓冲区大小有关系),总之就是一个数据包被分成了多次接收。
**解决方案**
#### 心跳机制 ####
### 协议层问题(协议设计) ###
#### 登录功能 ####
登录--指的是一个玩家在Socket连接上服务器后,还没开始游戏的一种状态,在这种状态下,客户端不应该接受任何关于游戏逻辑的消息。
完成登录功能需要设计以下协议:
1. LoginConn 协议,参数如下:
1. userName : string : 用户名(即用户ID)
2. password : string : 密码
当玩家按下登录按钮后,向服务器发送Login消息.
2. LoginResultConn 协议,参数如下:
1. userName : string : 用户名,用来标识唯一用户
2. loginStatus : string : 登录状态,success,fail这两种
当服务器收到Login消息后,解析协议,得到用户名和密码后,对数据库进行搜索,根据数据库是否存在用户名和密码,构造LoginResult协议给用户.
客户端额外处理:
当客户端接收到LoginStatus为Success的消息时,自动进入登录界面,即多人游戏--加入房间和创建房间的界面.
登录功能难点:
Login/LoginReuslt协议应该只在处于登录状态的用户之间传递,而不应该传递给那些已经登录完毕的单位.
在这里我的解决方法是,服务端使用一个ChannelGroup(记为LoginChannelGroup)来存储所有加入进来的连接(Channel),当一个用户登录完成后,LoginChannelGroup应该关闭这条连接(Channel),并将这条连接加入到另一个ChannelGroup中(此处记为RoomChannelGroup).
另一个难点,我使用反射的方法来对消息进行分发,同时,HandlerConn用于处理玩家未登录前的状态,HanlerPlayer用于处理玩家登录后的游戏逻辑处理.问题在于,我应该如何判断某个消息应该分发到HandlerConn中还是HanlerPlayer.
我采用的解决方法是,对协议名进行限定,即所有处理玩家未登录前状态的协议,其名称均会有Conn这几个字.
#### 房间系统 ####
房间系统指的是,玩家在登录状态完成后,将会进入多人游戏大厅,在游戏大厅中,用户可以加入其它人的房间进行游玩,或者自己创建房间等待其它玩家。
房间系统的特别之处在于在同一房间内的玩家发送的信息,只会被服务器转发给同一房间的玩家,其他玩家(处于登录状态/处于其他房间)都收不到在这个房间内被互相传递的信息.
完成登录功能需要设计以下协议:
1. CreateRoom 创建房间协议,用户点击创建房间按钮,向服务器发送创建房间的信息,参数如下:
1. userName : string : 创建房间的用户名
2. roomName : string : 创建的房间的名字
2. CreateRoomResult 创建房间结果协议,由服务器受到CreateRoom协议后发往客户端,表示此次创建房间的行动是否成功。(谁发送CreateRoom协议,那么谁就会接受CreateRoomResult协议),参数如下:
1. userName : string : 创建房间的用户名
2. roomName : string : 创建的房间的名字
3. RoomResult : string : "success"表示加入成功,"fail"表示加入失败
4. FailReason : string : 失败原因
2. AttendRoom 加入房间协议,用户点击加入房间按钮,向服务器发送加入房间的消息,参数如下:
1. roomName : string : 要加入的房间的名字
2. userName : string : 要加入该房间的用户
3. AttendRoomResult 加入房间结果协议,用于返回客户端加入房间的信息,表示是否成功.同时,会返回给用户这个房间的具体情况,比如,具体有哪几个玩家,分别是什么阵营的,叫什么名字等等.需要注意的是,该消息会发送给目标房间内的所有玩家(用于更新他们的客户端)
1. roomName : string : 要加入的房间的名字
2. userName : string : 要加入该房间的用户
3. RoomResult : string : "success"表示加入成功,"fail"表示加入失败
4. FailReason : string : 失败原因
4. GetRoomList 获得所有房间的协议信息,用于返回目前服务器上所有的房间信息,协议参数如下:
1. roomCount : int : 目前服务器一共有的房间数量,后面roomCount次数据都是下面这种格式
1. roomName : string : 房间名
2. roomPerson : int : 房间人数
3. roomStatus : string : 房间游戏状态(是否已经开始游戏)
房间系统流程:
玩家登录 -> 进入房间列表 -> 点击 加入房间 or 创建房间 -> 发送 CreateRoom 或 AttendRoom协议 -> 如果是CreateRoom协
没有合适的资源?快使用搜索试试~ 我知道了~
MOBA游戏的服务端,基于Java的Netty框架编写.zip
共73个文件
java:31个
class:28个
xml:6个
1.该资源内容由用户上传,如若侵权请联系客服进行举报
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
版权申诉
0 下载量 109 浏览量
2024-03-23
23:13:39
上传
评论
收藏 7.56MB ZIP 举报
温馨提示
MOBA游戏的服务端,基于Java的Netty框架编写
资源推荐
资源详情
资源评论
收起资源包目录
MOBA游戏的服务端,基于Java的Netty框架编写.zip (73个子文件)
java0323
MOBADemoServer.iml 942B
gitImage
show.gif 7.54MB
src
MainServer
handler
MOBAServerHandler.java 3KB
MOBAServer.java 2KB
Util
BitConverter.java 853B
Protocol
IProtocolBase.java 315B
ProtocolStr.java 775B
ProtocolBytes.java 3KB
test
client
EchoClient.java 1KB
EchChannelHandler.java 786B
SimpleClient.java 3KB
TestClient.java 2KB
test1.java 436B
model
MessageProto.java 23KB
server
TestServer.java 2KB
OnlyReceiveServerHandler2.java 377B
EchoServer.java 2KB
OnlyReceiveServerHandler.java 1KB
OnlyReceiveServer.java 2KB
decoder
MessageEncoder.java 829B
MessageEncoder1.java 800B
MyDecoder1.java 1KB
MyDecoder.java 1KB
SimpleChatServerInitializer.java 940B
TestServerHandler.java 3KB
EchoServerHandler.java 1KB
ProtocolDispatcher
HandlePlayerMsg.java 14KB
HandleConnMsg.java 2KB
META-INF
MANIFEST.MF 57B
PlayerLogic
RoomSystem
RoomModel.java 1KB
RoomSystem.java 1KB
RoomPlayer.java 645B
Scene
ScenePlayer.java 624B
Scene.java 692B
out
production
MOBADemoServer
Util
BitConverter.class 975B
Protocol
IProtocolBase.class 198B
ProtocolStr.class 902B
ProtocolBytes.class 3KB
test
client
TestClient.class 2KB
EchChannelHandler.class 2KB
EchoClient.class 2KB
EchoClient$1.class 1KB
SimpleClient.class 3KB
model
MessageProto.class 3KB
MessageProto$Message.class 13KB
MessageProto$Message$Builder.class 14KB
MessageProto$1.class 979B
MessageProto$MessageOrBuilder.class 400B
MessageProto$Message$1.class 1KB
server
SimpleChatServerInitializer.class 2KB
OnlyReceiveServer$1.class 2KB
EchoServerHandler.class 3KB
TestServer$1.class 1KB
OnlyReceiveServerHandler2.class 943B
OnlyReceiveServerHandler.class 3KB
OnlyReceiveServer.class 3KB
EchoServer.class 3KB
decoder
MyDecoder1.class 1KB
MessageEncoder.class 1KB
MyDecoder.class 2KB
TestServer.class 2KB
TestServerHandler.class 4KB
META-INF
MOBADemoServer.kotlin_module 16B
readme.md 19KB
.idea
description.html 97B
vcs.xml 180B
workspace.xml 44KB
misc.xml 403B
compiler.xml 711B
modules.xml 268B
encodings.xml 191B
.gitignore 29B
META-INF
MANIFEST.MF 57B
共 73 条
- 1
资源评论
Kwan的解忧杂货铺
- 粉丝: 1w+
- 资源: 3625
下载权益
C知道特权
VIP文章
课程特权
开通VIP
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功