Sử dụng WebSocket trong trình chạy dịch vụ

Hướng dẫn này minh hoạ cách kết nối với WebSocket trong trình chạy dịch vụ của tiện ích Chrome. Bạn có thể tìm thấy ví dụ về cách làm việc trên GitHub.

Thông tin khái quát

Kể từ Chrome 116, trình chạy dịch vụ tiện ích sẽ được hỗ trợ tốt hơn cho WebSockets. Trước đây, một trình chạy dịch vụ có thể trở nên không hoạt động mặc dù kết nối WebSocket đang hoạt động nếu không có sự kiện tiện ích nào khác xảy ra trong 30 giây. Thao tác này sẽ chấm dứt trình chạy dịch vụ và đóng kết nối WebSocket. Để biết thêm thông tin cơ bản về vòng đời của trình chạy dịch vụ tiện ích, hãy đọc hướng dẫn dành cho trình chạy dịch vụ tiện ích).

Từ Chrome 116 trở đi, bạn có thể giữ cho một trình chạy dịch vụ có kết nối WebSocket hoạt động bằng cách trao đổi thông báo trong cửa sổ hoạt động của trình chạy dịch vụ trong 30 giây. Những thao tác này có thể bắt đầu từ máy chủ hoặc từ tiện ích của bạn. Trong ví dụ sau, chúng ta sẽ gửi một thông báo thông thường từ tiện ích của Chrome tới máy chủ để đảm bảo rằng service worker vẫn hoạt động.

Ví dụ: WebSocket duy trì hoạt động

Trước tiên, chúng ta cần đảm bảo rằng tiện ích của mình chỉ chạy trong các phiên bản Chrome hỗ trợ WebSockets trong trình chạy dịch vụ bằng cách đặt phiên bản Chrome tối thiểu là 116 trong tệp kê khai:

manifest.json:

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

Sau đó, chúng ta có thể giữ cho worker này hoạt động bằng cách gửi thông báo giữ kết nối mỗi 20 giây. Giữ kết nối bắt đầu sau khi trình chạy dịch vụ kết nối với WebSocket. Ứng dụng WebSocket mẫu sau đây sẽ ghi nhật ký các thông báo và gọi keepAlive() khi sự kiện onopen được kích hoạt:

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

Bên trong keepAlive(), chúng ta sử dụng setInterval(...) để thường xuyên gửi một ping đến máy chủ khi có một kết nối WebSocket đang hoạt động:

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