שימוש ב-WebSockets ב-Service Workers

במדריך הזה נדגים איך להתחבר ל-WebSocket ב-Service Worker של תוסף ל-Chrome. אפשר למצוא דוגמה לעבודה ב-GitHub.

רקע

החל מגרסה 116 של Chrome, עובדי שירות של תוספים מקבלים תמיכה משופרת ב-WebSockets. בעבר, קובץ שירות (service worker) היה יכול להפוך ללא פעיל למרות שחיבור WebSocket היה פעיל אם לא התרחשו אירועי תוסף אחרים במשך 30 שניות. פעולה זו תסגור את Service Worker ותסגור את החיבור ל-WebSocket. לקבלת רקע נוסף על מחזור החיים של קובץ שירות של תוסף, קרא את המדריך לעובד שירות של תוסף.

החל מגרסה 116 של Chrome, אפשר להשאיר קובץ שירות (service worker) עם חיבור WebSocket פעיל על ידי החלפת הודעות בתוך חלון הפעילות של קובץ השירות (service worker) של ה-30 שניות. ניתן להפעיל אותן מהשרת שלך או מהתוסף שלך. בדוגמה הבאה נשלח הודעה רגילה מתוסף Chrome לשרת כדי להבטיח שה-Service Worker יישאר פעיל.

דוגמה: WebSocket keepalive

ראשית, עלינו לוודא שהתוסף שלנו פועל רק בגרסאות Chrome שתומכות ב-WebSockets ב-service worker, על ידי הגדרת הגרסה המינימלית של Chrome ל-116 במניפסט:

manifest.json:

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

לאחר מכן נוכל להשאיר את קובץ השירות פעיל על ידי שליחת הודעת הודעת keep-alive כל 20 שניות. ה-Keepalive מופעל ברגע ש-Service Worker מתחבר ל-WebSocket. הדוגמה הבאה של לקוח WebSocket מתעדת הודעות וקוראת ל-keepAlive() כשהאירוע 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();
}

בתוך 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 
  );
}