1,websocket
一,什么是websocket
WebSocket是HTML5下一种新的协议(websocket协议本质上是一个基于tcp的协议)
它实现了浏览器与服务器全双工通信,能更好的节省服务器资源和带宽并达到实时通讯的目的
Websocket是一个持久化的协议
二,websocket的原理
websocket约定了一个通信的规范,通过一个握手的机制,客户端和服务器之间能建立一个类似tcp的连接,从而方便它们之间的通信
在websocket出现之前,web交互一般是基于http协议的短连接或者长连接
websocket是一种全新的协议,不属于http无状态协议,协议名为"ws/wss"
webscoket是双向的,可以向服务端发送数据,服务端也可以推送数据,使用方法如下,
var lockReconnect = false;//避免重复连接
function reconnect(url) {
if(lockReconnect) {
return;
};
lockReconnect = true;
//没连接上会一直重连,设置延迟避免请求过多
tt && clearTimeout(tt);
tt = setTimeout(function () {
WebSocketTest(url);
lockReconnect = false;
}, 4000);
}
//socket链接
function WebSocketTest(url)
{
if ("WebSocket" in window)
{
alert("您的浏览器支持 WebSocket!");
// 打开一个 web socket
var ws = new WebSocket(url);
ws.onopen = function()
{
// Web Socket 已连接上,使用 send() 方法发送数据
ws.send("发送数据");
//连接上就开始心跳检测,检测websocket是否失去链接
heartCheck.start()
alert("数据发送中...");
};
ws.onmessage = function (evt)
{
heartCheck.start()
alert("数据已接收...");
};
ws.onclose = function()
{
// 关闭 websocket
alert("连接已关闭...");
};
ws.onerror = function() {
console.log('发生异常了');
reconnect(url);
};
}
else
{
// 浏览器不支持 WebSocket
alert("您的浏览器不支持 WebSocket!");
}
}
WebSocketTest('ws://localhost:9998/echo')
websocket缺点:websocket容易断连
解决方法:心跳检测机制检测websocket是否断连,如果失去链接,则重新链接
//心跳检测
var heartCheck = {
timeout: 3000,
timeoutObj: null,
serverTimeoutObj: null,
start: function(){
console.log('start');
var self = this;
this.timeoutObj && clearTimeout(this.timeoutObj);
this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj);
this.timeoutObj = setTimeout(function(){
//这里发送一个心跳,后端收到后,返回一个心跳消息,
console.log('55555');
ws.send("123456789");
self.serverTimeoutObj = setTimeout(function() {
console.log(111);
console.log(ws);
ws.close();
// createWebSocket();
}, self.timeout);
}, this.timeout)
}
}
2, eventSource服务端推送
eventSource是用来代替轮询的一种方案,它是单向,只能由服务端推送给客户端,客户端并不能给服务端传输数据
const es=new EventSource(`http://12313/123/interface`)
function initEventSource() {
if (typeof EventSource !== 'undefined') {
es.onmessage = e => {
console.log(e.data)
}
es.onerror = err => {
console.log(err)
}
es.addEventListener('ping', e => {
console.log(e)
})
es.addEventListener('start', e => {
console.log(e)
})
es.addEventListener('times', e => {
console.log(e)
})
} else {
this.$message.error('您的浏览器不支持 server-sent 事件 ..."')
}
}
initEventSource()
//eventsource需要主动关闭,所以在关闭页面时候需要执行关闭方法
function closeEventSource(){
es.close()
}
closeEventSource()
3,轮询
轮询可以服务端与客户端双向通信,但是如果数量多的话,服务器压力会大,原理就是通过定时器去一直请求,下方实例代码为每3s请求一次
setInterval(() => {
post('123', { id: 1 }).then(res => {
console.log(res)
})
}, 3000)