【基础】为什么使用WebSocket?
前端和后端的交互模式最常见的就是前端发数据请求,后端响应传输数据之前端进行展示。如果前端不操作,后端不能主动向前端推送数据。
因此,在业务场景需服务端主动向客户端推送消息,同时客户端也可以主动向服务端发送消息时,那就有了WebSocket的用武之地。
【特点】WebSocket的特点如下:
(1)建立在 TCP 协议之上,服务器端的实现比较容易。
(2)与 HTTP 协议有着良好的兼容性。默认端口也是80和443,并且握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器。
(3)数据格式比较轻量,性能开销小,通信高效。
(4)可以发送文本,也可以发送二进制数据。
(5)没有同源限制,客户端可以与任意服务器通信。
(6)协议标识符是ws
(如果加密,则为wss
),服务器网址就是 URL。
【注意点】在Vue使用WebSocket需注意以下几点:
(1)当前浏览器对WebSocket的兼容性如下:兼容性
image(2)在组件加载的时候连接websocket,在组件销毁的时候断开websocket
(3)后端接口需要引入socket模块,否则不能实现连接。
1.基础版
1.0 原生WebSocket基本介绍
事件 | ||
---|---|---|
open | Socket.onopen | 连接建立时触发 |
message | Socket.onmessage | 客户端接收服务端数据时触发 |
error | Socket.onerror | 通信发生错误时触发 |
方法 | |
---|---|
Socket.send() | 使用连接发送数据 |
Socket.close() | 关闭连接 |
属性 | |
---|---|
readyState 只读属性 | 表示连接状态 |
bufferedAmount 只读属性 | 已被 send() 放入正在队列中等待传输,但是还没有发出的 UTF-8 文本字节数 |
1.1代码分析(当前版本包含心跳机制)
<script>
export default {
components: { VueQr },
data() {
return {
lockReconnect: false, //是否真正建立连接
timeout: 58 * 1000, //58秒一次心跳
timeoutObj: null, //心跳心跳倒计时
serverTimeoutObj: null, //心跳倒计时
timeoutnum: null, //断开 重连倒计时
};
},
created() {
this.initWebSocket();
},
destroyed() {
this.websock.close(); //离开路由之后断开websocket连接
},
methods: {
currentTime() {
setInterval(this.formatDate, 500);
},
initWebSocket() {
//初始化weosocket
const wsuri = "wss://xxxxxxx/xx/xx/" + this.roomId;
this.websock = new WebSocket(wsuri);
// 客户端接收服务端数据时触发
this.websock.onmessage = this.websocketonmessage;
// 连接建立时触发
this.websock.onopen = this.websocketonopen;
// 通信发生错误时触发
this.websock.onerror = this.websocketonerror;
// 连接关闭时触发
this.websock.onclose = this.websocketclose;
},
// 连接建立时触发
websocketonopen() {
//开启心跳
this.start();
//连接建立之后执行send方法发送数据
// let actions = {"room":"007854ce7b93476487c7ca8826d17eba","info":"1121212"};
// this.websocketsend(JSON.stringify(actions));
},
// 通信发生错误时触发
websocketonerror() {
console.log("出现错误");
this.reconnect();
},
// 客户端接收服务端数据时触发
websocketonmessage(e) {
console.log(e.data);
//收到服务器信息,心跳重置
this.reset();
},
websocketsend(Data) {
//数据发送
this.websock.send(Data);
},
// 连接关闭时触发
websocketclose(e) {
//关闭
console.log("断开连接", e);
//重连
this.reconnect();
},
reconnect() {
//重新连接
var that = this;
if (that.lockReconnect) {
return;
}
that.lockReconnect = true;
//没连接上会一直重连,设置延迟避免请求过多
that.timeoutnum && clearTimeout(that.timeoutnum);
that.timeoutnum = setTimeout(function () {
//新连接
that.initWebSocket();
that.lockReconnect = false;
}, 5000);
},
reset() {
//重置心跳
var that = this;
//清除时间
clearTimeout(that.timeoutObj);
clearTimeout(that.serverTimeoutObj);
//重启心跳
that.start();
},
start() {
//开启心跳
console.log("开启心跳");
var self = this;
self.timeoutObj && clearTimeout(self.timeoutObj);
self.serverTimeoutObj && clearTimeout(self.serverTimeoutObj);
self.timeoutObj = setTimeout(function () {
//这里发送一个心跳,后端收到后,返回一个心跳消息,
if (self.ws.readyState == 1) {
//如果连接正常
// self.ws.send("heartCheck"); //这里可以自己跟后端约定
} else {
//否则重连
self.reconnect();
}
self.serverTimeoutObj = setTimeout(function () {
//超时关闭
self.ws.close();
}, self.timeout);
}, self.timeout);
},
},
mounted() {
this.currentTime();
},
// 销毁定时器
beforeDestroy() {
if (this.formatDate) {
clearInterval(this.formatDate); // 在Vue实例销毁前,清除时间定时器
}
},
};
</script>
网友评论