Open
Description
长轮询和短轮询
短轮询
短轮询:指的是客户端发起一个请求,服务器无论是否有新数据,都立即返回(有就返回新数据,没有就返回一个表示数据为空的响应),然后http连接断开。
setInterval(function () {
$.ajax('/user' , funciton (data) {
console.log(data);
})
} , 1000)
上面的代码就是每隔1秒钟向服务器发送一次请求,服务器返回数据,客户端再对数据进行处理。这里有一个问题需要注意,如果当前网络比较慢时,服务器从接受请求,返回数据到客户端接受请求的总时间有可能会超过1秒,而请求是每隔1秒发送一次,这样会导致接收的数据到达先后顺序与发送顺序不一致。于是我们可以采用setTimeout的方式来进行轮询,来避免这样的情况发生。
function poll () {
setTimeout(function () {
$.ajax('/user' , function (data) {
console.log(data);
poll();
})
} , 1000)
}
poll();
长轮询
长轮询:指的是由客户端发起请求,如果服务器没有相关数据,那么服务器会hold住请求,直到服务器有相关数据,或等待一定时间超时才会返回。返回后,客户端又会发起请求。这个是需要客户端和服务器两者共同来完成的,我们来简单实现一个:
客户端代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<h1>hello world</h1>
<button id="btn">获取用户信息</button>
<script>
var btn = document.getElementById('btn');
btn.addEventListener('click' , (e) => {
sendXhr();
});
function sendXhr () {
var xhr = new XMLHttpRequest();
xhr.open('get' , '/user');
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
var result = JSON.parse(xhr.responseText);
// 如果服务器没有数据,那么会再一次发起请求
if (!result['result']) {
sendXhr();
} else {
console.log('有数据了');
console.log(result);
}
} else {
console.log('失败');
}
}
};
xhr.send(null);
}
</script>
</body>
</html>
服务端代码:
const express = require('express');
const app = express();
app.set('view engine' , 'html');
app.engine('html' , require('ejs').renderFile);
app.set('views' , './views');
app.use('/public' , express.static('static'));
app.get('/' , (req , res) => {
res.render('./index.html');
});
app.get('/user' , (req , res) => {
function sleep(count) {
function inner () {
let timer = setTimeout(function () {
if (count == 1) {
clearTimeout(timer);
return res.status(200).json({result : ''});
} else {
count--;
inner();
}
} , 1000)
};
inner();
};
sleep(5);
});
app.listen(3000 , () => {
console.log('listening port on 3000');
})
就简单实现了一下,通过上面代码可知,当在客户端点击按钮时,会向服务器发送请求,而服务器上的代码,则会hold住请求5秒,然后再将数据发送给客户端,当客户端判断数据为空的时候,又重新向服务器发送请求。长轮询就是这样的一个过程。
心跳机制
心跳机制:指的是客户端每隔N秒向服务器发送一个心跳消息,服务器收到客户端的心跳小心后,回复同样的心跳消息给客户端,如果服务器或客户端再M秒(M>N)内没有收到心跳消息在内的任何消息,即心跳超时,那么我们就认为该连接已经断开了。