为什么有了HTTP协议还需要WebSocket协议?

95 阅读3分钟

首先需要知道的是WebSocket协议HTTP协议一样都是应用层的协议,都是基于TCP的协议。

但是既然有了HTTP协议为什么还需要WebSocket协议呢,这说明HTTP协议存在一些缺点,最主要的就是: HTTP协议中通信是单向的,请求只能由客户端发起,客户端不发,服务器就不答,服务器不会主动推送数据给客户端。这就是【半双工】。

但是什么时候需要用到服务器主动给客户端发送数据的功能呢?也就是什么时候需要用到全双工的功能呢?(客户端和服务端都能在同一时间里主动向对方发送数据)

接下来就来讲WebSocket协议的应用场景,比如在网页游戏里,有大量的需要由服务端主动发给客户端的数据,比如怪物对玩家产生伤害的数据。

知道了WebSocket协议的应用场景后,我们就可以讲讲WebSocket连接是怎么建立的

  • 刚开始他和http连接的建立没什么不同,都是先TCP三次握手之后开始连接,但这时候WebSocket还不会主动出现,你想用到它必须得依靠HTTP协议来和服务端进行通信,告诉服务端你想要升级成WebSocket连接。
  • 所以TCP三次握手之后,会先使用HTTP协议先进行一次通信,通过在HTTP请求头里带上特殊的字段
    Connection: Upgrade
    Upgrade: WebSocket
    Sec-WebSocket-Key: <一串随机生成的base64码>
    
  • 服务器收到Request Header之后,就会明白浏览器想升级协议,并且想升级成WebSocket协议。
  • 如果服务器支持这个请求的话,就会根据客户端生成的base64码,用某个公开算法变成另一段字符串,放在HTTP响应头Sec-WebSocket-Accept里面,并且带上101的状态码,发回给浏览器。
  • 这里101的状态码是指服务器同意客户端切换协议的请求,并且告诉客户端自己即将切换协议。
  • 浏览器收到响应头后,浏览器也用同样的算法自己的那串乱码转成另一段字符串,如果跟服务器传回来的字符串一致,那么验证通过
  • 到此为止,用HTTP协议进行的一次通信已经完成了,说明WebSocket建立完成了。那么后续客户端和服务端就可以使用WebSocket协议进行通信了。

要注意的是,WebSocket协议是用在客户端和服务端之间需要频繁交互的场景,如果对于某些简单场景,HTTP协议也能通过一些小手段来伪造服务端"主动"给客户端推送数据的功能。

比如,最常见的网页上扫码登陆场景,你会发现你用手机打开vx扫完码后,网页停顿一会会儿就能实现登陆成功网页跳转了。这一般就是由HTTP协议来做的,通过轮询伪造服务端"主动"给客户端推送数据的功能。

由于网页不知道用户有没有扫码成功,不知道什么时候该跳转页面,所以通过轮询,也就是不断去向后端服务器询问这个用户到底登陆了没,基本是以大概1秒2秒的间隔去不断发出请求。但是这样不间断的请求会导致HTTP请求非常多,会给服务器造成一定压力。还有一个缺点就是用户会感到明显的卡顿。

所以还有一种优化的解决方案,就是长轮询

长轮询其实就是延长一个HTTP请求到一个比较长的时间,比如30s。把HTTP请求的超时设置成30s,在这30s内,服务器只要收到了扫码请求,就会立马返回给客户端告诉客户端有人登录了,这样大大减少了HTTP请求个数。