学习总结
-
为什么websocket可以是实现长连接
因为websocket的底层是使用的socket进行了封装
-
websocket的连接协议
(1)客户端发送过来会有一个key代码如下
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Origin: http://example.com
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
其中最重要的是
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
(2)服务器收到了以后会对这个随机的key 进行migic的操作,然后在进行sha-1加密,base-64加密然后在发送给客户端
migic = “258EAFA5-E914-47DA-95CA-C5AB0DC85B11”;
客户端会收到下面的包数据
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
WebSocket-Location:ip: port
Sec-WebSocket-Protocol: chat
其中Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo= 这个就是加密后的东西
如果服务器发送了这个数据的话,就证明客户端和服务器已经做好了连接。
3.为什么websocket没有粘包和断包的问题
因为在底层websocket已经封装了一套发送包的结构,这样我们不必在向socket那样对二进制进行封装包,解析包的操作
结构是:固定的长度+包长度+mark掩码+数据的封装方式,有了这个底层的封装,我们不必关心粘包断包的问题使用起来相当的愉快。
4.基础的代码实现:在npm的网站有ws的基础代码使用
服务器代码
//引入ws包
const ws = require("ws");
//创建socket server对象
const wss = new ws.Server({port:6666});//监听本地6666端口
//事件监听
//错误事件
wss.on("error",(error)=>{
console.log("error",error);
})
//关闭事件
wss.on("close",()=>{
console.log("close");
})
//连接事件
wss.on("connection",(client_sock)=>{
console.log("have a client connection");
client_sock.on("message",(data)=>{
console.log(data);
client_sock.send("thank you!!!");
})
client_sock.on("error",(error)=>{
console.log("error",error);
})
client_sock.on("close",()=>{
console.log("client is close");
})
})
客户端代码:
//客户端的demo
const ws = require("ws");
//创建websocket对象
const Websocket = new ws("ws://127.0.0.1:6666/ws");
//监听事件
Websocket.on("open",()=>{
//收到连接的消息
Websocket.send("hello");
})
//错误消息
Websocket.on("error",(error)=>{
console.log("error",error);
})
//收到消息信息
Websocket.on("message",(data)=>{
console.log(data);
})
//close事件
Websocket.on("close",()=>{
console.log("close");
})