Используйте WebSockets в сервис-воркерах

В этом руководстве показано, как подключиться к WebSocket в сервис-воркере вашего расширения Chrome. Рабочий пример вы можете найти на Github .

Фон

Начиная с Chrome 116, сотрудники служб расширений получают улучшенную поддержку WebSockets . Раньше сервисный работник мог стать неактивным, несмотря на активное соединение WebSocket, если в течение 30 секунд не происходило никаких других событий расширения. Это приведет к прекращению работы сервисного работника и закрытию соединения WebSocket. Дополнительные сведения о жизненном цикле работника службы расширения см. в руководстве для работника службы расширения ).

Начиная с Chrome 116, вы можете поддерживать активность сервис-воркера с подключением WebSocket, обмениваясь сообщениями в окне активности сервис-воркера в течение 30 секунд. Они могут быть инициированы либо с вашего сервера, либо с вашего расширения. В следующем примере мы отправим обычное сообщение из расширения Chrome на сервер, чтобы гарантировать, что сервис-воркер остается в живых.

Пример: поддержка активности WebSocket

Сначала нам нужно убедиться, что наше расширение работает только в версиях Chrome, поддерживающих WebSockets в сервис-воркерах, установив в манифесте минимальную версию Chrome 116:

манифест.json:

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

Затем мы можем поддерживать активность сервис-воркера, отправляя сообщение поддержки активности каждые 20 секунд. Поддержка активности запускается, как только сервисный работник подключается к WebSocket. Следующий пример клиента WebSocket регистрирует сообщения и вызывает метод keepAlive() при срабатывании события onopen :

сервис-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:

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