Chrome扩展开发使 Service Worker 保持活跃状态

Service Worker 设计为独立于单个页面的后台线程,它通常在没有控制任何页面(clients)时会被浏览器停止或处于等待状态。但是,如果你希望即使在插件页面关闭后,Service Worker 仍然保持活跃,可以尝试以下方法:

  • 使用多个页面:保持至少一个页面(如后台管理页面)打开,该页面由 Service Worker 控制。Service Worker 会随着最后一个它控制的页面关闭而停止。
  • 定期触发事件:如果你的 Service Worker 需要持续运行,可以设计一些逻辑,比如定期发送通知或执行后台同步,这样浏览器会认为 Service Worker 仍在使用中。

这里介绍一下定期触发事件。

  我们通过定期向浏览器扩展存储写入当前时间(称为“心跳”),来保持Service Worker的活跃状态。这种做法可以减少Service Worker因长时间不活动而被浏览器终止。

示例:

// Service Worker 主入口点
self.addEventListener('install', async () => {
  console.log('Service Worker installing...');
  // 在安装时启动心跳
  await startHeartbeat();
});

// 心跳函数定义
let heartbeatInterval;

async function runHeartbeat() {
  await chrome.storage.local.set({ 'last-heartbeat': new Date().getTime() });
}

async function startHeartbeat() {
  // 在Service Worker启动时立即运行一次心跳
  await runHeartbeat();
  // 然后每20秒运行一次
  heartbeatInterval = setInterval(runHeartbeat, 20 * 1000);
}

async function stopHeartbeat() {
  if (heartbeatInterval) {
    clearInterval(heartbeatInterval);
    heartbeatInterval = null;
  }
}

// Service Worker 激活事件
self.addEventListener('activate', async () => {
  console.log('Service Worker activating...');
  // 激活时,可能需要清理旧的心跳间隔
  await stopHeartbeat();
  // 然后重新启动心跳
  await startHeartbeat();
});

// Service Worker 消息事件
self.addEventListener('message', async (event) => {
  if (event.data === 'stopHeartbeat') {
    console.log('Stopping heartbeat...');
    await stopHeartbeat();
  } else if (event.data === 'startHeartbeat') {
    console.log('Starting heartbeat...');
    await startHeartbeat();
  }
});

// Service Worker Fetch 事件
self.addEventListener('fetch', (event) => {
  // 在处理fetch事件时,可以临时启动心跳以保持活跃
  console.log('Handling fetch event...');
  // 这里可以根据需要决定是否启动心跳
});

// 当Service Worker即将被关闭时
self.addEventListener('beforeunload', async () => {
  console.log('Service Worker beforeunload...');
  // 停止心跳
  await stopHeartbeat();
});

// 监听并处理错误,确保Service Worker稳定运行
self.addEventListener('error', (event) => {
  console.error('Service Worker error:', event);
});

// 监听并处理安装失败事件
self.addEventListener('installerror', (event) => {
  console.error('Service Worker install error:', event);
});

// 监听并处理活动失败事件
self.addEventListener('activateerror', (event) => {
  console.error('Service Worker activate error:', event);
});

 

posted @ 2024-06-21 14:48  当下是吾  阅读(25)  评论(0编辑  收藏  举报