websocket是什么

了解websocket之前首先要说一下HTTP。
首先我们想象一下大部分的用户在操作网页时,用户在页面上点击一下按钮前端会给后台服务器发送一次HTTP请求 ,后台返回一次HTTP响应。
但是这种方式的前提都是用户自己请求(点击页面)的方式太被动了,而且只有在请求之后服务器才会做出反应!

那么怎么才能让服务器给用户主动发消息,让他主动一点呢?
webSocket应运而生

webSocket解决的痛点

在没有webSocket的过去在针对这种场景用HTTP时的解决方案是啥呢?
方式一:
让用户不做任何操作让网页能收到信息并发生变更。
以前的方式是在前端代码里不断定时发HTTP请求给后端服务器,服务器收到请求之后相应给前端相应消息。
但这是一种伪服务器推送的方式,他并不是服务器主动,而是前端偷偷请求服务器只是对于用户来说无感知而已。
如扫码登陆就会用到这种方式,在这种操作下前端其实也不知道用户有没有扫码,只是不断的用1到2秒的时间给后端发送请求去询问。(HTTP定时轮询)

方式二:
像上述的方式我们在网页进入开发者模式会看到很多HTTP请求后台服务器的记录,这样消耗带宽的同时也会增加服务器的负担。那有没有更好的方式去解决这个问题呢?
有!很有!非常有! 而且实现成本还非常的低!也就是“长轮询”
我们把超时的时间改长一些比如设置成30秒,在30秒内只要服务器收到了扫描请求就立马返回给客户端进行登录。
如果超出30秒视为超时但是再立马发送下一次请求。这样就完美解决了HTTP请求的次数从而减少了服务器的开销。
于是这种发起请求在较长时间内等待服务器反馈的机制就叫做长轮询机制。

常用的消息队列rocketMQ中消费者取数据时也用到了长轮询。
而这种在用户不感知的情况下服务器将数据推送给浏览器的技术就是服务器推送技术。

但是!但是!但是!这两种方式本质还是前端主动服务器被动的!
于是基于TCP的新的应用层的webSocket协议就被设计出来了

webSocket是如何使用的

在正常访问页面时通常都会先用HTTP协议进行握手,当需要用到webSocket连接时会在HTTP请求中增加特殊的Header头
如:

connection:Upgrade用来表明浏览器想要升级协议
Upgrade:webSocket用来表示客户端想升级成webSocket协议
Sec-WebSocket-Key:base64

这是服务器也支持那么将会升级成webSocket协议,然后开始走webSocket握手流程
根据Sec-WebSocket-Key通过算法得出一个新的字符串,将他放在HTTP中ses-ws-accept里再加上101返回给浏览器

HTTP/1.1 101 Switching Protocols //101指协议切换
ses-ws-accept
Upgrade: websocket
Connection: Upgrade

浏览器用同样的算法将BASE64码转成另一段字符串,如果跟服务器传过来的字符串一致那么验证通过。

webSocket和HTTP

他们都是基于TCP的协议
webSocket在经历三次TCP三次握手之后将HTTP协议升级成webSocket协议,后续双方就通过webSocket协议进行通讯了

数据包在webSocket中被称为帧,下图为帧的数据格式
webSocket协议-LMLPHP

  • opcode
    这里标注了这是一个什么类型的数据帧。比如1是指text类型(String类型)、2是指2进制的数据包、8为关闭连接信号
  • payload
    想要传输的数据长度,单位是字节

webSocket完美继承了TCP的双全工能力,并且还提供了解决粘包的方案,适用于服务器和客户端频繁交互的大部分场景。
如:网页聊天、小程序游戏、协调办公软件
补充:
websock只是在建立连接的过程中会用到HTTP,升级成webSocket协议之后就跟HTTP没有一点关系了,HTTP只是扮演了短暂的工具人角色。

10-22 17:53