这是我参与8月更文挑战的第20天,活动详情查看:8月更文挑战
什么是WebSocket?
WebSocket 是HTML5 中的协议,支持持久连续,http 协议不支持持久性连接。Http1.0 和HTTP1.1 都不支持持久性的链接,HTTP1.1 中的keep-alive,将多个http 请求合并为 1 个
WebSocket 是什么样的协议,具体有什么优点?
HTTP 的生命周期通过Request 来界定,也就是Request 一个Response,那么在Http1.0 协议中,这次Http 请求就结束了。在Http1.1 中进行了改进,是的有一个connection: Keep-alive,也就是说,在一个Http 连接中,可以发送多个Request,接收多个Response。 但是必须记住,在Http 中一个Request 只能对应有一个Response,而且这个Response 是被动的,不能主动发起。 WebSocket 是基于Http 协议的,或者说借用了Http 协议来完成一部分握手,在握手阶段 与Http 是相同的。我们来看一个websocket 握手协议的实现,基本是2 个属性,upgrade, connection。
基本请求如下:
- GET /chat HTTP/1.1
- Host: server.example.com
- Upgrade: websocket
- Connection: Upgrade
- Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
- Sec-WebSocket-Protocol: chat, superchat
- Sec-WebSocket-Version: 13
- Origin: example.com
告诉服务器发送的是websocket
- 1.Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
- 2.Sec-WebSocket-Protocol: chat, superchat
- 3.Sec-WebSocket-Version: 13
其他特点包括:
(1)建立在 TCP 协议之上,服务器端的实现比较容易。
(2)与 HTTP 协议有着良好的兼容性。默认端口也是80和443,并且握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器。
(3)数据格式比较轻量,性能开销小,通信高效。
(4)可以发送文本,也可以发送二进制数据。
(5)没有同源限制,客户端可以与任意服务器通信。
(6)协议标识符是ws(如果加密,则为wss),服务器网址就是 URL。
应用(vue+WebSocket创建实现实时通讯)
创建websocket(构造函数)
let wsuri = this.$api.teaback.createWSChatListenUrl(tokenRet.listen_token);
websock = new WebSocket(wsuri);
websock.onopen
实例对象的onopen属性,用于指定连接成功后的回调函数
websock.onopen = this.websocketonopen;
async websocketonopen() {
console.log("WebSocket连接成功");
this.imgStatus = true;
this.callKeepAlive();
},
websock.onclose
实例对象的onclose属性,用于指定连接关闭后的回调函数。
//关闭连接
async websocketclose(e) {
console.log("断开连接", e);
websock = null;
this.imgStatus = false;
setTimeout(this.initWebSocket, restart_time);
this.killKeepAlive();
},
websock.onmessage
实例对象的onmessage属性,用于指定收到服务器数据后的回调函数。
//接收后端返回的数据
async websocketonmessage(e) {
let data = e.data;
},
websock.send()
实例对象的send()方法用于向服务器发送数据。
callKeepAlive() {
this.killKeepAlive();
keepalive_id = setInterval(function () {
if (websock) websock.send("keepalive");
}, 9000);
if (websock) websock.send("keepalive");
},
websock.onerror
实例对象的onerror属性,用于指定报错时的回调函数
//连接建立失败重连
async websocketonerror(e) {
console.log(`连接失败的信息:`, e);
//this.initWebSocket() // 连接失败后尝试重新连接
this.imgStatus = false;
websock = null;
this.killKeepAlive();
if (!exitFlag) setTimeout(this.initWebSocket, restart_time);
},