WS(WebSocket)是应用层协议,允许客户端和服务端全双工通信。
HTTP协议有一比较大的缺陷,那就是通信只能由客户端发起,不能实现服务端主动发消息给客户端,客户端想要获知服务器的状态变化,只能通过轮询或者长轮询等方式,效率很低且浪费资源,WS就是为了解决这一问题出现的。

WS和HTTP对此:
相同点:
1.都是基于TCP的应用层协议;
2.都使用Request/Response模型进行连接的建立;
3.在连接过程中对错误的处理方式相同,在这个阶段WS可能返回和HTTP相同的返回码;
4.都可以在网络中传输数据。

不同点:
1.WS使用HTTP来建立连接,但是定义了一系列新的header域,这些域在HTTP中不会被使用;
2.WS的连接不能通过中间人来转发,它必须是一个直接连接;
3.WS连接建立之后,通信双方都可以在任何时刻向另一方发送数据;
4.WS连接建立之后,数据的传输使用帧来传递,不再需要request消息;
5.WS的数据帧有序。

WS通信过程

WS是基于TCP的一个应用协议,与HTTP协议的关联之处在于WS的握手数据被HTTP服务器当作HTTP包来处理,主要通过Update request HTTP包建立连接,之后的通信全部使用WS自己的协议。过程如上图所示,握手请求报文头部如下

GET /uin=xxxxxxxx&app=xxxxxxxxx&token=XXXXXXXXXXXX HTTP/1.1
Host: server.example.cn:443
Connection: Upgrade
Pragma: no-cache
Cache-Control: no-cache
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36
Upgrade: websocket
Sec-WebSocket-Version: 13
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: user_id=XXXXX
Sec-WebSocket-Key: 1/2hTi/+eNURiekpNI4k5Q==
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
Sec-WebSocket-Protocol: binary, base64

第一行是请求的方法,类型必须为GET,协议版本号必须大于1.1
Upgrade字段必须包含,值为WebSocket
Connection字段必须包含,值为Upgrade
Sec-WebSocket-Key字段必须包含,记录着握手过程中必不可少的键值
Sec-SebSocket-Protocol字段必须包含,记录着使用的子协议
Origin(请求头):Origin用来指明请求的来源,Origin头部主要用于保护WS服务器免受非授权的跨域脚本调用WS API的请求。也就是不想没被授权的跨域访问与服务器建立连接,服务器可以通过这个字段来判断来源的域,并有选择的拒绝。

WS有什么特点
1.与HTTP协议有良好的兼容性;
2.建立在TCP协议之上,和HTTP协议同属应用层;
3.数据格式比较轻量,性能开销小,通信高效;
4.可以发送文本,也可以发送二进制;
5.没有同源限制,可以与任意服务器通信。

HTTP和WS和区别
HTTP协议是短连接,因为请求之后,都会关闭连接,下次请求需要重新打开连接。
WS协议是一种长连接,只需要通过一次请求来初始化连接,然后所有请求和响应都是通过TCP连接进行通信的。

WebSocket和Socket的区别
Socket是应用层与TCP/IP协议通信的中间软件抽象层,它是一组接口。而WebSocket协议是一个完整的应用层协议,拥有一套完整的API。