项目新版本发布后,怎么用技术手段通知用户刷新页面?

2,439 阅读3分钟

前言

在项目开发中,尤其是C端项目,有时候一些重大的更新,需要让用户知晓,通常是通过一个弹窗将更新信息展示给用户,今天我们就来看下,如何通过技术手段实时通知用户(展示这个提醒用户刷新页面的弹窗)。

使用 Service Worker

Service Worker 可以用于检测新版本的发布,并在检测到新版本时通知用户刷新页面。

注册 Service Worker

在你的主 JavaScript 文件中注册 Service Worker:

if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('/service-worker.js').then(registration => {
    registration.addEventListener('updatefound', () => {
      const newWorker = registration.installing;
      newWorker.addEventListener('statechange', () => {
        if (newWorker.state === 'installed' && navigator.serviceWorker.controller) {
          // 新版本已安装,通知用户刷新页面
          notifyUserAboutUpdate();
        }
      });
    });
  }).catch(error => {
    console.error('Service Worker registration failed:', error);
  });
}

function notifyUserAboutUpdate() {
  // 这里可以使用 alert、模态框、通知等方式通知用户
  alert('新版本已发布,请刷新页面以获取最新内容。');
}

Service Worker 文件(service-worker.js

self.addEventListener('install', event => {
  // 在安装过程中缓存资源
  event.waitUntil(
    caches.open('my-cache').then(cache => {
      return cache.addAll([
        // 列出需要缓存的资源
        '/',
        '/index.html',
        '/main.js',
        '/styles.css',
      ]);
    })
  );
});

self.addEventListener('fetch', event => {
  event.respondWith(
    caches.match(event.request).then(response => {
      return response || fetch(event.request);
    })
  );
});
使用 WebSocket

通过 WebSocket 连接,服务器可以实时通知客户端有新版本发布。

// 服务器端(Node.js 示例)
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });

wss.on('connection', ws => {
  // 在新版本发布时,向所有连接的客户端发送消息
  ws.send(JSON.stringify({ type: 'UPDATE_AVAILABLE' }));
});

// 客户端
const socket = new WebSocket('ws://localhost:8080');

socket.addEventListener('message', event => {
  const data = JSON.parse(event.data);
  if (data.type === 'UPDATE_AVAILABLE') {
    // 通知用户刷新页面
    alert('新版本已发布,请刷新页面以获取最新内容。');
  }
});
使用长轮询(Long Polling)

长轮询是一种模拟实时通信的方法,客户端定期向服务器发送请求以检查是否有新版本发布。

// 服务器端(Node.js 示例)
const express = require('express');
const app = express();

let isUpdateAvailable = false;

app.get('/check-update', (req, res) => {
  if (isUpdateAvailable) {
    res.json({ update: true });
  } else {
    res.json({ update: false });
  }
});

// 在新版本发布时设置标志
app.post('/new-version', (req, res) => {
  isUpdateAvailable = true;
  res.sendStatus(200);
});

app.listen(3000, () => {
  console.log('Server is running on port 3000');
});

// 客户端
function checkForUpdates() {
  fetch('/check-update')
    .then(response => response.json())
    .then(data => {
      if (data.update) {
        // 通知用户刷新页面
        alert('新版本已发布,请刷新页面以获取最新内容。');
      } else {
        // 继续轮询
        setTimeout(checkForUpdates, 60000); // 每分钟检查一次
      }
    })
    .catch(error => {
      console.error('Error checking for updates:', error);
      setTimeout(checkForUpdates, 60000); // 在错误情况下继续轮询
    });
}

// 开始轮询
checkForUpdates();
使用缓存控制(Cache-Control)

通过设置 HTTP 头来控制缓存,可以确保用户在发布新版本后获取最新的资源。

// 服务器端(Node.js 示例)
const express = require('express');
const app = express();

app.use((req, res, next) => {
  res.setHeader('Cache-Control', 'no-store');
  next();
});

app.use(express.static('public'));

app.listen(3000, () => {
  console.log('Server is running on port 3000');
});
  • Service Worker:适用于 PWA,可以离线缓存和版本控制。
  • WebSocket:实时通信,适用于需要即时通知的应用。
  • 长轮询:模拟实时通信,适用于不支持 WebSocket 的环境。
  • 缓存控制:通过 HTTP 头控制缓存,确保用户获取最新资源。

这其中有一个网络相关的面试题——短轮询、长轮询和WebSocket三者关系。其实性能上,短轮询<长轮询<WebSocket;兼容性上,短轮询>长轮询>WebSocket。

  • 短轮询:实现简单,但频繁请求会增加服务器和网络负担,实时性较差。
  • 长轮询:减少了请求次数,实时性较好,但实现相对复杂,需要服务器支持长时间保持连接。
  • WebSocket:提供真正的实时双向通信,资源消耗低,但实现复杂,适用于需要高实时性和频繁数据更新的应用。

具体用哪个技术,还是要结合项目实际情况来进行选择。