闽公网安备 35020302035485号

2.同样,如果客户端在毫秒内 pingInterval + pingTimeout 未收到来自服务器的 ping,则客户端也会认为连接已关闭。
// 客户端的CODE
io.on('custom-ping', function () {
io.emit('custom-pong', Date.now())
})
// 服务端CODE
io.on('connection', (socket) => {
console.log('New client connected');
// 发送自定义ping消息
const pingInterval = setInterval(() => {
socket.emit('custom-ping', Date.now());
}, 10000); // 每10秒发送一次
// 堆代码 duidaima.com
// 监听自定义pong消息
socket.on('custom-pong', (data) => {
console.log('Pong received:', data);
});
socket.on('disconnect', () => {
clearInterval(pingInterval);
console.log('Client disconnected');
});
});
注意:断连时一定要销毁定时器
// 以下setTimeout仍然会丢失精度
let _cacheTs = Date.now()
const _setTimeoutFn = () => {
console.log('setTimeout :>> ', Date.now() - _cacheTs);
_cacheTs = Date.now()
setTimeout(() => {
_setTimeoutFn()
}, 5000)
}
_setTimeoutFn()
在setTimeout里面去执行一个函数栈会被浏览器监控到,会认为和setInterval一样,其在后台运行时会降低其定时精度。但如果这样可以避开节能机制的限制:// 客户端CODE
// 监听服务端发送的custom-pong事件
socket.on('custom-pong', onHeart)
const onHeart = () => {
if (timer) {
clearTimeout(pingTime.current)
}
timer = window.setTimeout(() => {
socket.emit('custom-ping', Date.now())
}, 5000)
}
// 服务端CODE
socket.on('custom-ping', ()=>{
socket.emit('custom-pong', Date.now())
})
使用Web-Workersconst noSleepInstance = new NoSleep();
document.addEventListener('click', function enableNoSleep() {
document.removeEventListener('click', enableNoSleep, false);
noSleepInstance.enable();
}, false);
实测,使用这种方式时,浏览器在后台运行仍然存在定时器精度降低的问题。在实际排查中,是从第七步倒退排查发现是浏览器节能机制所引起的问题。。。