游戏开发—协议设计

本篇是游戏开发系列第一篇,如若你有兴趣,请持续关注,后期会持续更新。其余文章列表以下:算法

游戏开发—协议设计json

游戏开发—协议-protobuf后端

游戏开发-协议-protobuf原理详解浏览器


通俗地说,协议就是通讯双方可以理解的一种数据格式。维基百科这么定义网络协议:安全

网络协议为计算机网络中进行数据交换而创建的规则、标准或约定的集合。bash


协议设计包含三要素:服务器

语法:语法是用户数据与控制信息的结构与格式,以及数据出现的顺序。网络

语义:解释控制信息每一个部分的意义。它规定了须要发出何种控制信息,以及完成的动做与作出什么样的响应。数据结构

时序:时序是对事件发生顺序的详细说明并发


也就是说,语义表示要作什么,语法表示要怎么作,时序表示作的顺序。咱们要基于此来设计个人协议。

一般游戏有一些特殊性,好比流量要尽可能的少,安全性要求更高,以及对平台支持足够多等等。这一切的需求就要求游戏协议设计,尽可能简单、通用,以及代码层上易扩展、解析效率足够高等特色。

基于此,我须要从如下几个层次来考虑游戏协议的设计方案。


1、知识图谱

由于知识点比较多,建议先读知识图谱,对总体结构有一个清晰的综括。

2、协议三个层次


应用层

应用层主要是经常使用是解析方式定义和解析,主要的选型,主要是看你基于什么需求了,适用于实际需求就好。咱们经常使用的协议类型,主要有这两种:文本协议、二进制协议


一、文本协议:

文本协议设计的目的就是方便人们理解,读懂。如常见的http协议,通常的常见http协议以下:

GET/sample.Jsp HTTP/1.1
Accept:image/gif.image/jpeg,*/*
Accept-Language:zh-cn
Connection:Keep-Alive
Host:localhost
User-Agent:Mozila/4.0(compatible;MSIE5.01;Window NT5.0)
Accept-Encoding:gzip,deflate
username=test&password=1234复制代码


这种格式很是贴近咱们的文字描述,方便阅读,并且目前HTTP也是客户端浏览器或其余程序与Web服务器之间的应用层通讯协议,适用很是普遍。但你也看到,有时候基于一个很简单应答,就要带上不少其余的头信息,这对于对流量有要求的游戏应用来讲,仍是很浪费的。

优势

一、通用,适用普遍

二、方便理解,可读性好

缺点:

一、基于行读,解析效率通常

二、携带附带信息过多,传输的效率低下

三、无状态,服务器不知道客户端的状态,必须基于客户端的请求来回应,实时性低

四、很难嵌入其余数据,对二进制支持差

若是你的游戏对实时性要求不高,并且对流量要求不也是过高,文本协议也是个不错的方式。通常短链接游戏多适用这个。


二、二进制协议

二进制协议就是一串字节流,是一个典型的Ip协议,通常一般包括消息头(header)和变长的消息体(body),消息头的长度固定,消息体长度不固定,包含主要的内容主体。通常消息头会包含消息体的长度,这样就能基于头信息从数据流中解析出一个完整的二机制消息了。

通常的格式以下:


咱们看到head部分定义包含:

cmd:命令字

sign:验证串

content-leg:消息体长度

HeaderCRC:头验证(不是必须)

其中命令字是双方协议文档中规定好的,好比0x01表示登录,0x02表示注册等等,这些就是一个命令号。

sign是一个验证字符串,对消息体数据进行必定加密验证,保证数据安全。

content-leg是本次消息体的长度。


body部分,好比咱们以下定义:

message:login{

string username;

int64 passwoard;

}

咱们看到,由于字段的数据类型有定义,顺序也有定义(第一个是string,第二个是int64),整个二进制流读取的的时候,基于顺序读取就能够很快的取出了。

优势

一、没有冗余字段,传输高效,耗费流量小

二、解析速度快,基于基础数据类型操做

缺点:

一、可读性差,不利于调试

二、扩展性差,对复杂数据结构支持不够

若是你的游戏,对实时性要求比较高,流量有要求,用二进制比较好,通常大型多人网游,使用二进制协议来设计。


三、数据格式

以上咱们看到了两种协议类型,但对于消息体的解析介绍不多,消息体的格式决定了的他的语义和时序,格式不一样数据的序列化和反序列化也是不一样。好比message:login,你能够基于json来定义,也能够基于xml来定义,定义不一样解析方式也各不相同。

通常的消息体格式主要有如下几种:json、protocolBuff、xml、自定义

json

json 是一种轻量级的数据交换格式,互联网应用的很普遍了。经常使用的框架也不少,推荐fastJson,解析速度仍是不错的。json的好处是,开源,格式统一,解析速度也还能够。缺点就是会有一些冗余字符,不够简洁。

protocolBuff

protocolBuff是是google提供的一个开源序列化框架,相似于XML,JSON这样的数据表示语言。可是比这些占用空间都小,没有冗余字段。并且好处是灵活,解析速度快,易于开发(基于配置自动生成代码),可支持语言也比较多。一条消息数据,用protobuf序列化后的大小是json的10分之一,xml格式的20分之一,是二进制序列化的10分之一

xml

很少解释了,你们都用有过,强烈不建议使用这种,除了无效字符过多(标签),并且解析效率比上面两种都是很低的。

自定义

本身定义就是本身定义解析方式,好比经过文档定义好一个消息的结构,第一个字段是什么类型,第二个字段什么类型...等等,基于此本身写工具解析。好处是对外协议不透明,解析效率和传送效率都还不错,缺点就是开发难度高,不容易维护。

各类格式优缺点以下:


2、安全层

游戏通讯,安全也很重要,否则协议被破解,用户刷资源,整个游戏的平衡性就被破坏了,轻者影响其余玩家体验,重则游戏直接被废。

通常的安全处理就是对协议进行加密。通常有如下几种:

一、常规加密

采用对称加密或者hash加密来对消息内容进行加密,两端采用同一种加密算法,基于同一个密钥对消息体进行加密换算,以此来查看数据是否一致。

密钥能够用户登录的时候获取一次。还有一种是基于每一个用户密钥不一样,以此防止密钥泄露大范围影响全服玩家。

二、动态加密

动态加密,能够提早设置一个私有密钥库,里面包含必定数量的密钥,每次客户端请求的时候,基于协议号来设计一个算法获取其中一个密钥。每一个协议的密钥都是在协议到达的时候时时获取的,这样即使某一个协议的密钥被破解,对其余协议依然无效。

三、其余

采用非对称加密,或者加盐处理。非对称加密速度太慢了,不建议。


3、传送层

考虑服务端的承载成本,以及手机游戏上网络环境差,原则上UDP是比TCP更适合的方式。可是因为游戏对于数据完整性、安全性要求比较高,采用TCP的又可靠与安全。

目前采用netty做为推送服务器的也有支持上百万链接的应用了,tcp这块性能对于通常游戏支持足够了。长连接游戏多采用分区分服来应对高并发压力,短连接多采用分布式来应对。


4、一些问题

一、字节序

二进制协议中,字节序须要注意,跨语言、平台通讯的时候会出现乱码问题。目前的字节序主要有,Little endian和Big endian之分,也就是常说的大头和小头之分。

具体是大头在前仍是小头在前,这个和主机的cpu有关系PowerPC系列采用big endian方式存储数据,而x86系列则采用little endian方式存储数据。这个在手机主机上也会出现。

应对方案是:

客户端和服务端强制采用一种字节序,通常采用网络字节序(big endian)


二、浮点数

协议中出现浮点类型要特别注意,浮点类型的传送上面字节序处理OK了,还得注意浮点数的多平台运算不一致问题。

好比游戏中要对寻路、战斗等公式计算,牵扯到浮点数了,有可能先后端算出的不一致,以Arm为例,Arm的浮点数就有软模拟、硬件IEEE-754兼容、SIMD下IEEE-754不兼容三种状况。

此时解决方案,

一、统一一种格式,好比先后端都采用软模拟,或者强制采用硬件IEEE-754(软模拟速度慢)

二、转换为定点数,也就是浮点转换为整数(速度快)


扫描关注个人公众号

相关文章
相关标签/搜索