本文解决如下几个问题:
1.什么是长连接,什么是短连接
2.在什么情况下,游戏使用长连接或是短连接
3.在使用短连接时,该采用何种网络数据的收发方式
4.在短连接时是否采用http协议
0.起因
前段时间,看到一个开源的Unity客户端架构,在处理网络层时,该架构采用的方式如下:
var response = await session.Call(request)
该方式采用了协程,发送一个请求协议,再等待一个返回协议,这是一种典型的请求-响应的协议设计,类似的如Http协议也是这类设计。但游戏制作毕竟不是网页响应,初看这段代码的时候,对于这个设计框架的作者的思路,表示了怀疑。举例说明,如果玩家登录游戏到得到角色列表这一流程,按着这种请求响应的设计思路,该流程如下:
发送一个登录协议->收到登录协议的返回,如果结果无误->发送角色请求协议->收到角色请求协议的返回数据整个流程在网络层产生了四次数据传输。但其实就性能与效率而言,这不是一个好的设计方案。在设计协议时,我们一般的方案如下:
发送一个登录协议,服务端收到登录协议,如结果有误,向客户端发送返回协议,如果结果无误,不返回结果协议,直拉向DB请求数据库,收到DB的数据返回,向客户端发送角色数据。对于客户端来说,他的协议如下:
成功时:发送一个登录协议->收到角色列表同步协议
失败时:发送一个登录协议->收到登录协议的出错协议
整个流程在客户端与服务器之间,只产生了两次数据传递。除了减少了数据传输之个,这样设计,还有一个原因,请求角色这类的协议,直接暴露给客户端,让它操作数据库,是服务器安全性的一个弊端。如果客户端反复发送这条协议,会引起不必要的麻烦。
回到网络上来,网络编程中,并不是所有协议都有返回协议的,很多广播协议就并没有返回协议,也不需要。协议并不是一个响应,更底层来说,协议是一件事件。
用道具来说明这一流程,如果有两个道具协议,一个是删除道具,一个是使用道具,在设计协议时,在删除道具和使用道具成功时,都可以不用发送返回协议,而是由服务端,发送一个道具同步协议,只有在出错时,发送出错提示协议。这样设计的好处在于,道具的修改会被束在有限的一个处理点上。
以上,是我当时的想法,但昨天,我对这个认知,产生了一些新的理解。
var response = await session.Call(request)
是有必要存在的,但它并不适合所有方案。要深入讨论,我们需要从长连接与短连接说起。
1.什么是长连接,什么是短连接?
一般我们说的长连接与短连接,在游戏制作时,指的是用TCP还是HTTP。但其实上,这两个概念是没有比较性的。这两个概念在网络层的两个层级上。Http也可以是长连接,1.1之后的版本,只要Connection:Keep-alive,这个通讯就没有中断。
我们说长短连接的时候,真正要说的是,是否需要TCP的三次握手,以及TCP的消息安全机制。TCP是一种可靠的传输,在消息的底层,它为我们确认了消息是否有序,消息是否到达对端,网络传输是一个异常复杂的过程,即使先发A信息,发再B信息,但是在对端收到的时候,也有可能是B先于A到达,但因为有TCP,它验证了顺序,保证了上层协议的有序,在上层逻辑处理网络缓冲区时,先取出来一定是A,而不是B。但非TCP连接则不,因为没有这些安全机制的检查,所以非TCP连接在一定程序上要快过TCP连接。
2.在什么情况下,游戏使用长连接或是短连接
重度的手机游戏,像RPG类的,MOBA类的游戏,都采用的TCP连接。但消消乐这类的游戏,显然采用短连接更好一些,因为它并不是时刻与服务器连接在一起的。
3.在使用长连接与短连接时,该采用何种网络数据的收发方式
既然我们要使用短连接,那么该以何种方式,来确定这些信息是发送到了对端的呢。如果再在逻辑层加一组机制来判断,那还不如直接使用TCP机制。答案其实很简单,就是上面的await代码,采用请求-响应的协议设计。
4.在短连接时是否采用http协议
我个人认为是不需要的。Http是文本协议,对于游戏来说,如果每次协议来回都要加上Http的请求头与返回头是很消耗流量的。本来发送一个升级协议,只需要不到4个byte,加上这些头,来来回回就是50个byte。短连接与Http协议不是1对1的关系。
不论使用那种应用层协议,自定义也好http也好。对于底层来说,总有一个Socket通道存在,TCP机制,决定了这个Socket通道中的数据,是我们信任的,一定会到达对端的。如果出错网络错误,该通道会被底层关闭,此时,上层逻辑也会收到Socket被关闭的消息。但是一个非TCP机制,是没有这样的检测条件的。举例说明,我们刷网页的时候,如果网络太慢,一直会转圈,内容得不到显示。我们键入地址回车时,虽然发出了请求指令,但其实上他有没有到对端,我们是不知道的。只有当显示出了文字,这个请求看上去被响应了,这个操作被认为是完成了。如果一直得到回应怎么办?过一段时间就会超时。
超时是短连接处理网络问题的一个办法。为什么会超时?是因为使用的是请求响应这种协议设计,一个请求,必须要有一个响应,没有响应数据到来,要么数据可能丢掉了,要么这个网络也许断开了。
综上,如果在游戏制作过程中,使用非TCP机制的连接,在协议设计上一定要基于请求响应这种设计方案,可以更快检查出当前网络的状态。在这种情况下,是否采用HTTP协议,却并不是必须的。采用google protobuf依然还是首选。
转载:https://blog.csdn.net/setup_pf/article/details/105612417