大部分网页功能场景是 HTTP请求 服务器返回HTTP响应
但仍然存在需要服务器主动发消息,客户端接收的情况
问题的关键在于:如何在用户不主动进行操作的情况下,网页主动接收数据并及时发生变更
有以下常见解决方案:
1.伪服务器推:
利用HTTP定时轮询,定时发送HTTP请求到服务器
- 优点:
用户无感知且成本极低 - 缺点:
用户概率感知明显卡顿,且会占用带宽且增加下游服务器负担
2.长轮询:
将HTTP请求超时设置的很大,在较长时间内等待服务器响应,例如百度网盘的扫码登录就是用的这种长轮询机制
- 优点:
用户无感知且响应及时,同时成本极低 - 缺点:
仍然会占用带宽且增加下游服务器负担,且本质还是客户端主动请求数据没有整整解决问题,只能用于简单场景
3.websocket:
以上两种方法本质还是客户端主动请求数据 只能使用扫码等简单场景。
为应付网页游戏,网页聊天,网页协同办公等复杂场景,websocket协议应运而生。
TCP是全双工协议,通信两端都可以主动向对方发送数据。
HTTP1.1基于TCP协议,但只支持同一时间段的单向通信,也就是半双工。
websocket协议同样基于TCP,在HTTP的基础上使用。若某一页面需要用到websocket,则需要在HTTP请求中带上特殊的header:
connection:Upgrade
客户端想要升级通信协议
Upgrade:websocket
升级为websocket
Sec-WebSocket-Key
随机base64码 用于协议升级转换后的通信验证
- 优点:
基本解决了客户端需要与服务器频繁交互的大部分场景 - 缺点:
增加了系统的开发维护成本,服务器长期维护长连接的性能消耗不小,且各个浏览器支持程度不一。
如何使用
initWebSocket () {
if ('WebSocket' in window) {
this.websock = new WebSocket(`ws:${
process.env.projectConfig.websockApi}`);//这个连接ws://固定,后面的根据自己的IP和端口进行改变,我设置监听的就是8081
}
this.websock.onmessage = this.websocketonmessage
this.websock.onerror = this.websocketonerror
this.websock.onopen = this.websocketonopen
this.websock.onclose = this.websocketclose
},
websocketonopen () {
//
console.log('连接成功');
this.websock.send({
});
this.timer = window.setInterval(()=>{
//每隔5秒钟发送一次心跳,避免websocket连接因超时而自动断开
console.log('每隔5秒钟发送一次心跳');
this.websock.send({
});
},5000);
},
websocketonerror () {
//连接错误
console.log( 'WebSocket连接失败')
this.error_action() //自动重连
},
websocketonmessage (e) {
// 数据接收
console.log('接收到消息,准备xxxx',e);
let data = JSON.parse(e.data)
//xxx的功能代码
},
websocketclose (e) {
// 关闭连接
console.log('已关闭连接', e)
this.error_action() //自动重连
},
error_action(){
console.log('重新连接');
clearInterval(this.timer);
this.chonglian_action();
},
chonglian_action() {
//重连方法
//判断有没有网 此处代码后加的,为了优化没网实例化socket时候的报错问题
if(!navigator.onLine){
return ;//没网就中断
}
//readyState 0尚未建立连接 1连接已经建立 2连接正在关闭 3连接已经关闭或不可用
// if(this.websock.readyState==0||this.websock.readyState==3){
this.initWebSocket()
console.log('开始重新连接');
// }
}
},
destroyed () {
this.websock.close() // 页面销毁后断开websocket连接
}