WebSockets in Service Workern verwenden

In dieser Anleitung wird gezeigt, wie Sie im Service Worker Ihrer Chrome-Erweiterung eine Verbindung zu einem WebSocket herstellen. Ein funktionierendes Beispiel finden Sie auf GitHub.

Hintergrund

Ab Chrome 116 erhalten Erweiterungs-Service-Worker einen verbesserten Support für WebSockets. Früher konnte ein Service Worker inaktiv werden, obwohl eine WebSocket-Verbindung aktiv war, sofern 30 Sekunden lang keine anderen Erweiterungsereignisse aufgetreten sind. Dadurch würde der Service Worker beendet und die WebSocket-Verbindung geschlossen. Weitere Informationen zum Lebenszyklus des Erweiterungsdienst-Workers finden Sie im Leitfaden für Erweiterungs-Service-Worker.

Ab Chrome 116 können Sie einen Service Worker mit einer WebSocket-Verbindung aktiv lassen, indem Sie innerhalb des Service Worker-Aktivitätsfensters Nachrichten austauschen. Diese Anfragen können entweder über Ihren Server oder über Ihre Erweiterung initiiert werden. Im folgenden Beispiel senden wir eine reguläre Nachricht von der Chrome-Erweiterung an den Server, um sicherzustellen, dass der Service Worker aktiv bleibt.

Beispiel: WebSocket Keepalive

Zuerst müssen wir sicherstellen, dass unsere Erweiterung nur in Chrome-Versionen ausgeführt wird, die WebSockets in Service Workern unterstützen. Dazu setzen wir die Mindestversion von Chrome im Manifest auf 116:

manifest.json:

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

Dann können wir den Service Worker aktiv halten, indem wir alle 20 Sekunden eine Keepalive-Nachricht senden. Das Keepalive wird gestartet, sobald der Service Worker eine Verbindung zum WebSocket hergestellt hat. Der folgende Beispiel-WebSocket-Client protokolliert Nachrichten und ruft keepAlive() auf, wenn das onopen-Ereignis ausgelöst wird:

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

Innerhalb von keepAlive() verwenden wir setInterval(...), um regelmäßig einen Ping an den Server zu senden, während eine aktive WebSocket-Verbindung vorhanden ist:

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