这是我参与「第四届青训营 」笔记创作活动的的第四天
写在前面
在写大项目时,有个需求需要服务端和客户端的持久化通信,需要服务端主动请求客户端,因此我去学习webSocket。以下是我的一些学习笔记。
HTTP实现服务端与客户端实时通信
- http通信是单向的,即只能客户端请求服务端,没有请求就没有响应,通信只能由客户端发起,服务端做不到主动向客户端推送消息。若服务端获取到最新的消息(例如最新的聊天信息、最新的天气信息等),客户端想获取到这些最新的消息,只能通过ajax轮询或长轮询等方式
- ajax轮询
- 客户端设置一个ajax请求,每隔一段时间就向服务端发送一个请求,询问服务端是否有最新的消息
- 长轮询
- 和ajax轮询类似,不过是采用阻塞模型,就好像是电话占线一样,没有新消息就不挂掉电话。具体实现就是客户端发起请求时,如果没有消息,服务端就一直不返回响应给客户端,直到有最新的消息。之后继续建立连接,以此循环
- 如上方法虽然一定程度上实现了服务端和客户端的“实时通信”,但缺点也十分明显:不断建立http请求或长时间占有http请求十分地浪费资源,增加服务器和网络负担。
初识webSocket
- 与http不同,webSocket真正意义上实现了客户端与服务端的即使通信,它不仅让客户端可以主动请求服务端,同时也让服务端可以主动请求客户端,让通信双方没有客户端服务端之分,提供的就是端对端通信了
- http与webSocket的通信示意图
webSocket协议
- 首先我们要明确的是,webSocket对客户端与服务端的第一次握手是基于HTTP协议来完成的
- 来自客户端的握手请求头举例
Get ws://localhost/chat HTTP/1.1 Host:localhost Upgrade:WebSocket//告诉升级成什么,如此表示升级为WebSocket Connection:Upgrade//标识该HTTP请求是一个协议升级请求 Sec-WebSocket-Key:dGh1IHNhbXBsZSBub25jZQ==//标识客户端 Sec-WebSocket-Extensions:permessage-deflate//协议扩展类型 Sec-WebSocket-Version:13//客户端支持WebSocket的版本- Sec-WebSocket-Key
- 客户端采用base64编码的24位随机字符序列,服务端接收客户端HTTP协议升级的证明。要求服务端相应一个对应加密的Sec-WebSocket-Accept头信息作为应答
- Sec-WebSocket-Key
- 来自服务端的握手响应头举例
HTTP/1.1 101 Switching Protocols Upgrade:webSocket Connection:Upgrade Sec-WebSocket-Accept:s3pPLMBiTxaQ9kYGzzhZRbK+xOo=//标识服务端 Sec-WebSocket-Extensions:permessage-deflate
写在最后
以上便是我的一些学习笔记,若有不足,欢迎指出