From fc1f6a19797ce3cb1d4a3fccc7c697962cb8d229 Mon Sep 17 00:00:00 2001 From: evgeny Date: Wed, 17 Apr 2024 12:30:57 +0100 Subject: [PATCH 1/3] docs: update Ably JS in Chrome extension --- README.md | 15 ++++-- docs/chrome-mv3.md | 114 --------------------------------------------- 2 files changed, 12 insertions(+), 117 deletions(-) delete mode 100644 docs/chrome-mv3.md diff --git a/README.md b/README.md index 9f0e122507..3bd40af1c5 100644 --- a/README.md +++ b/README.md @@ -511,9 +511,18 @@ This library currently does not support being the [target of a push notification - ["Unable to parse request body" error when publishing large messages from old versions of Internet Explorer](https://support.ably.com/solution/articles/3000062360-ably-js-unable-to-parse-request-body-error-when-publishing-large-messages-from-old-browsers). -#### Manifest v3 Chrome Extensions -Chrome extensions built with Manifest v3 require service workers instead of background pages. -This is supported in Ably via the [Web Worker build](#supported-platforms), however [workarounds](docs/chrome-mv3.md) are required to ensure Chrome does not mark the service worker as inactive. +#### Chrome Extensions +Ably supports Chrome extensions out-of-the-box since v2. However, extension service workers get improved support for +WebSockets only starting with Chrome 116. Therefore, it is necessary to ensure that the extension runs only on Chrome +versions supporting WebSockets in service workers by setting the minimum Chrome version to 116 in the manifest: + +```json +{ + ... + "minimum_chrome_version": "116", + ... +} +``` #### Next.js with App Router and Turbopack diff --git a/docs/chrome-mv3.md b/docs/chrome-mv3.md deleted file mode 100644 index 4a24eae63b..0000000000 --- a/docs/chrome-mv3.md +++ /dev/null @@ -1,114 +0,0 @@ -# Using Ably in a Chrome Extension with Manifest v3 - -In Manifest V3, Chrome extensions can [no longer use background pages in favor of service workers](https://developer.chrome.com/docs/extensions/mv3/migrating_to_service_workers/). -Chrome will [mark a service worker as inactive even if an active WebSocket connection is made](https://bugs.chromium.org/p/chromium/issues/detail?id=1152255). -This causes Ably to disconnect and new messages will not be received. -Unfortunately, this appears to be intended design so workarounds are needed to keep the service worker alive in order to continue receiving messages. Multiple workarounds are available, depending on your use-case. - -### Using alarms - -Alarms will reset the service worker's inactivity timer, or wake up an inactive service worker. -The alarm must have a period of less than 5 minutes in order to keep a service worker active consistently. -The minimum period required depends on the actions that your service worker performs, but it has to be at most 4.9 minutes. -Requires permission `alarms` to be added to manifest.json: - -```json -{ - // ... - "permissions": ["alarms"] -} -``` - -```js -chrome.alarms.create({ periodInMinutes: 0.3 }); -chrome.alarms.onAlarm.addListener(() => { - // This function will be called once the SW wakes up -}); -``` - -[More Info](https://developer.chrome.com/docs/extensions/reference/alarms/) - -### Connecting to a nativeMessaging host - -If your Chrome extension connects to a native application, a service worker which is attached to a native application will not be marked as inactive as long as the native application is alive. To ensure that the native application exiting does not mark your service worker as inactive, make sure the connection can survive a restart of the native application. - -```js -var port = chrome.runtime.connectNative('com.example.extension'); -port.onDisconnect.addListener(function () { - // Reconnect to avoid being marked as inactive -}); -``` - -[More Info](https://developer.chrome.com/docs/apps/nativeMessaging/) - -### Connecting to a tab - -If your Chrome extension requires broad host permissions (e.g. `*://*/*`), connecting to a tab will keep your service worker active. -Requires `scripting` permission to be added to manifest.json: - -```json -{ - // ... - "permissions": ["scripting"] -} -``` - -```js -findTab(); -chrome.runtime.onConnect.addListener((port) => { - if (port.name === 'keepAlive') { - setTimeout(() => port.disconnect(), 250e3); - port.onDisconnect.addListener(() => findTab()); - } -}); - -const onUpdate = (tabId, info, tab) => /^https?:/.test(info.url) && findTab([tab]); -async function findTab(tabs) { - if (chrome.runtime.lastError) { - /* tab was closed before setTimeout ran */ - } - for (const { id: tabId } of tabs || (await chrome.tabs.query({ url: '*://*/*' }))) { - try { - await chrome.scripting.executeScript({ target: { tabId }, func: connect }); - chrome.tabs.onUpdated.removeListener(onUpdate); - return; - } catch (e) {} - } - chrome.tabs.onUpdated.addListener(onUpdate); -} -function connect() { - chrome.runtime.connect({ name: 'keepAlive' }).onDisconnect.addListener(connect); -} -``` - -[More Info](https://developer.chrome.com/docs/extensions/reference/scripting/) - -### Connecting to a port - -If you connect to a port, the service worker's inactivity timer will be reset. However, the port must be reconnected at an interval less than 5 minutes or the SW will be marked as inactive. - -```js -chrome.runtime.onConnect.addListener((port) => { - if (port.name !== 'foo') return; - port.onMessage.addListener(() => {}); - port.onDisconnect.addListener(deleteTimer); - port._timer = setTimeout(forceReconnect, 250e3, port); -}); -function forceReconnect(port) { - deleteTimer(port); - port.disconnect(); -} -function deleteTimer(port) { - if (port._timer) { - clearTimeout(port._timer); - delete port._timer; - } -} -``` - -[More Info](https://developer.chrome.com/docs/extensions/reference/runtime/#method-connect) - -### Enterprise Extensions - -[Enterprise extensions will continue to work on manifest v2 until January 2024](https://developer.chrome.com/docs/extensions/mv3/mv2-sunset/). -If your extension is installed as part of an enterprise policy, this means that you will have until January 2024 to continue using manifest v2. From fb52cd48b2c6c1733f9275a6c4a81f72c216e737 Mon Sep 17 00:00:00 2001 From: Evgeny Khokhlov Date: Wed, 17 Apr 2024 21:20:54 +0100 Subject: [PATCH 2/3] docs: apply suggestions from code review Co-authored-by: Owen Pearson <48608556+owenpearson@users.noreply.github.com> --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 3bd40af1c5..af008485b8 100644 --- a/README.md +++ b/README.md @@ -512,9 +512,9 @@ This library currently does not support being the [target of a push notification - ["Unable to parse request body" error when publishing large messages from old versions of Internet Explorer](https://support.ably.com/solution/articles/3000062360-ably-js-unable-to-parse-request-body-error-when-publishing-large-messages-from-old-browsers). #### Chrome Extensions -Ably supports Chrome extensions out-of-the-box since v2. However, extension service workers get improved support for -WebSockets only starting with Chrome 116. Therefore, it is necessary to ensure that the extension runs only on Chrome -versions supporting WebSockets in service workers by setting the minimum Chrome version to 116 in the manifest: +ably-js works out-of-the-box in background scripts for Chrome extensions using manifest v2. However, since manifest v3 background pages are no longer supported so you will need to run ably-js inside a service worker. +If you are using an ably-js realtime client in a service worker, note that in version of Chrome before 116 active WebSockets would not reset the 30s service worker idle timer which would result in the client being closed prematurely, however in versions 116 and above, service workers will stay active as long as a client is connected. +You can ensure that your extension only runs in versions 116 and above by adding the following to your `manifest.json`: ```json { From e04a57490c1268ff75fd5fb1ebca2c9658abf323 Mon Sep 17 00:00:00 2001 From: Evgeny Khokhlov Date: Tue, 23 Apr 2024 17:10:40 +0100 Subject: [PATCH 3/3] docs: update wording based on review Co-authored-by: Andrew Bulat --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index af008485b8..a139165f29 100644 --- a/README.md +++ b/README.md @@ -513,7 +513,7 @@ This library currently does not support being the [target of a push notification #### Chrome Extensions ably-js works out-of-the-box in background scripts for Chrome extensions using manifest v2. However, since manifest v3 background pages are no longer supported so you will need to run ably-js inside a service worker. -If you are using an ably-js realtime client in a service worker, note that in version of Chrome before 116 active WebSockets would not reset the 30s service worker idle timer which would result in the client being closed prematurely, however in versions 116 and above, service workers will stay active as long as a client is connected. +If you are using an ably-js realtime client in a service worker, note that in versions of Chrome before 116, active WebSockets would not reset the 30s service worker idle timer, resulting in the client being closed prematurely, however, in versions 116 and above, service workers will stay active as long as a client is connected. You can ensure that your extension only runs in versions 116 and above by adding the following to your `manifest.json`: ```json