En este instructivo, se muestra cómo conectarse a un WebSocket en el service worker de tu extensión de Chrome. Puedes encontrar un ejemplo funcional en GitHub.
Fondo
A partir de Chrome 116, los service workers de extensiones tendrán mejor compatibilidad con WebSockets. Anteriormente, un service worker podía volverse inactivo a pesar de que una conexión de WebSocket estuviera activa si no se producían otros eventos de extensión durante 30 segundos. Esto finalizaría el service worker y cerraría la conexión de WebSocket. Para obtener más información sobre el ciclo de vida del service worker de la extensión, consulta la guía del service worker de la extensión.
A partir de Chrome 116, puedes mantener activo un service worker con una conexión WebSocket intercambiando mensajes dentro de la ventana de actividad del service worker de 30 s. Se pueden iniciar desde tu servidor o desde tu extensión. En el siguiente ejemplo, enviaremos un mensaje normal desde la extensión de Chrome al servidor para asegurarnos de que el service worker permanezca activo.
Ejemplo: Keepalive de WebSocket
Primero, debemos asegurarnos de que nuestra extensión solo se ejecute en las versiones de Chrome que admiten WebSockets en los service workers. Para ello, configuraremos la versión mínima de Chrome en 116 en el manifiesto:
manifest.json:
{
...
"minimum_chrome_version": "116",
...
}
Luego, podemos mantener activo el service worker enviando un mensaje de keepalive cada 20 s. El keepalive se inicia una vez que el service worker se conecta al WebSocket. El siguiente cliente de WebSocket de muestra registra mensajes y llama a keepAlive() cuando se activa el evento onopen:
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();
}
Dentro de keepAlive(), usamos setInterval(...) para enviar un ping al servidor de forma periódica mientras haya una conexión de WebSocket activa:
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
);
}