Gebruik WebSockets in servicemedewerkers

Deze handleiding laat zien hoe je verbinding maakt met een WebSocket in de service worker van je Chrome-extensie. Een werkend voorbeeld is te vinden op GitHub .

Achtergrond

Vanaf Chrome 116 bieden extensieserviceworkers verbeterde ondersteuning voor WebSockets . Voorheen kon een serviceworker inactief worden, ondanks een actieve WebSocket-verbinding, als er gedurende 30 seconden geen andere extensiegebeurtenissen plaatsvonden. Dit leidde tot het beëindigen van de serviceworker en het verbreken van de WebSocket-verbinding. Lees de handleiding voor extensieserviceworkers voor meer informatie over de levenscyclus van extensieserviceworkers .

Vanaf Chrome 116 kun je een service worker met een WebSocket-verbinding actief houden door berichten uit te wisselen binnen het 30 seconden durende activiteitsvenster van de service worker. Deze berichten kunnen worden geïnitieerd door je server of door je extensie. In het volgende voorbeeld sturen we een regulier bericht vanuit de Chrome-extensie naar de server om ervoor te zorgen dat de service worker actief blijft.

Voorbeeld: WebSocket keepalive

Allereerst moeten we ervoor zorgen dat onze extensie alleen werkt in Chrome-versies die WebSockets in service workers ondersteunen. Dit doen we door de minimale Chrome-versie in het manifest in te stellen op 116:

manifest.json:

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

Vervolgens kunnen we de service worker actief houden door elke 20 seconden een keepalive-bericht te verzenden. De keepalive-functie wordt gestart zodra de service worker verbinding maakt met de WebSocket. De volgende voorbeeld-WebSocket-client logt berichten en roept keepAlive() aan wanneer de onopen gebeurtenis wordt geactiveerd:

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();
}

Binnen keepAlive() gebruiken we setInterval(...) om regelmatig een ping naar de server te sturen zolang er een actieve WebSocket-verbinding is:

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 
  );
}