在 Service Worker 中使用 WebSocket

本教程演示了如何在 Chrome 扩展程序的服务工程中连接到 WebSocket。您可以在 GitHub 上找到有效示例

背景

从 Chrome 116 开始,扩展程序 Service Worker 可以更好地支持 WebSockets。以前,如果 30 秒内没有发生其他扩展事件,即使 WebSocket 连接处于活动状态,Service Worker 也可能会变为非活动状态。这会终止 Service Worker 并关闭 WebSocket 连接。如需详细了解扩展程序服务工件生命周期,请参阅扩展程序服务工件指南

从 Chrome 116 开始,您可以通过在 30 秒的 Service Worker 活动窗口内交换消息,让具有 WebSocket 连接的 Service Worker 保持活跃状态。这些操作可以通过您的服务器或扩展程序发起。在以下示例中,我们将从 Chrome 扩展程序向服务器发送一条常规消息,以确保 Service Worker 保持活动状态。

示例:WebSocket 保持连接

首先,我们需要确保我们的扩展程序仅在支持服务工作器中的 WebSocket 的 Chrome 版本中运行,为此,请在清单中将最低 Chrome 版本设置为 116:

manifest.json:

{  ...  "minimum_chrome_version": "116",  ... } 

然后,我们可以通过每 20 秒发送一次 keepalive 消息来让服务工作器保持活跃状态。在 Service Worker 连接到 WebSocket 后,系统会启动 keepalive。以下示例 WebSocket 客户端会记录消息,并在 onopen 事件触发时调用 keepAlive()

service-worker.js

let webSocket = null; function connect() {  webSocket = new WebSocket('wss://example.com/ws');  webSocket.onopen = (event) => {  console.log('websocket open');  keepAlive();  };  webSocket.onmessage = (event) => {  console.log(`websocket received message: ${event.data}`);  };  webSocket.onclose = (event) => {  console.log('websocket connection closed');  webSocket = null;  }; } function disconnect() {  if (webSocket == null) {  return;  }  webSocket.close(); } 

keepAlive() 中,我们使用 setInterval(...) 在有有效 WebSocket 连接时定期向服务器发送 ping:

function keepAlive() {  const keepAliveIntervalId = setInterval(  () => {  if (webSocket) {  webSocket.send('keepalive');  } else {  clearInterval(keepAliveIntervalId);  }  },  // Set the interval to 20 seconds to prevent the service worker from becoming inactive.  20 * 1000   ); }