(一)WebSocket简介
短连接:在传统的Http协议中,客户端和服务器端的通信方式是短连接的方式,也就是服务器端并不会保持一个和客户端的连接,在消息发送后,会断开这个连接,客户端下次通信时,必须再建立和服务器的新连接,这就是短连接。在短链接的情况下,客户端必须不停的主动发起请求,而服务器始终被动的响应请求,来推送回数据。这种方式用到游戏开发中,显然是不适合的。
长连接:那么与之相对的就是长连接了。在长连接的情况下,客户端和服务器端始终保持一条有效的连接,那么客户端并不需要不停的主动发送消息,而服务器端也能主动的推送消息到客户端。很类似前面介绍的Socket的收发方式。那么显然长连接是我们游戏网络开发所需要的。
WebSocket:正是有了这样的需求,所以产生了WebSocket这一协议。注意,WebSocket只是一种协议,并不是一种Socket。WebSocket可以在客户端和服务器端建立一种全双工的通信连接。其协议是基于Tcp的方式实现的。
(二)WebSocket基础知识
1.握手
WebSocket其实就是使用Tcp建立连接,那么当终端建立连接时,怎么才能知道是一般的Tcp方式还是WebSocket协议方式呢?这里就需要靠握手,简单的说,通过握手机制,终端就能判别建立的是什么样的连接,从而决定是以WebSocket方式来处理还是Tcp方式来处理消息。
如果我们是自己实现服务器端,其实我们在收包的时候,就是一般的Tcp Socket的收包,并没有什么不同,该怎么处理还是怎么处理。但对于客户端就不一样了。因为大部分情况,客户端是使用现有的浏览器来作为客户端代码的JS运行环境的(除非你连客户端浏览器环境也是自己实现)。现有浏览器必须明确的知道协议类型,才能正确的建立长连接,并处理WebSocket包,并使用相关的JS代码,所以握手就变的及其重要了。
当实现我们自己的服务器时,建立握手的意义在于正确的通知客户端,服务器可以接收并允许建立一条基于WebSocket协议的连接
握手请求类似于下面这样的一段信息,不同的浏览器可能不一样,因为不同的浏览器遵循的WebSocket协议版本可能并不一致。
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Sec-WebSocket-Version: 13
Origin: http://localhost:5754
Sec-WebSocket-Extensions: permessage-deflate
Sec-WebSocket-Key: DC8b7Irs1RsyDvP2iEdsUQ==
Connection: keep-alive, Upgrade
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket
对于上面的内容,其实我们没必要知道太多,其中关键的是“Sec-WebSocket-Key”中的内容。稍后将做解释,我们先看服务器应该如何响应这样的握手。当服务器决定接收这个WebSocket连接时,服务器必须回发一段有效的Http response消息给客户端。这个很重要,因为只有发送正确的响应,客户端浏览器才能确认WebSocket请求被接收,才能正确的建立起WebSocket连接(其实说白了就是因为浏览器不是我们自己开发,假设你有那闲工夫,自己开发整个浏览器和WebSocket环境,握手协议想怎么定是你自己的事,否则就要遵循标准)。
正确的服务器返回响应如下:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
同样,不必过于关注具体内容,前面三行照抄就行了。我们只需要关注两个地方,一个是换行,一个是Sec-WebSocket-Accept
换行:上述消息中,前三行后必须跟一个换行符,最后一行后则要跟两个换行符
Sec-WebSocket-Accept*:这个值是一个经过加密处理的字符串,客户端将验证该值来判断是否成功建立WebSocket连接,因为这个值的正确与否相当重要。对该值的计算方法是,将发来请求时的Sec-WebSocket-Key与GUID值“258EAFA5-E914-47DA-95CA-C5AB0DC85B11”连接,然后将新字符串