Spec-Zone.ru › Web Extensions

runtime.Порт

Объект Port представляет собой один конец соединения между двумя конкретными контекстами, который может использоваться для обмена сообщениями.

Одна сторона инициирует соединение, используя API connect(). Это возвращает объект Port. Другая сторона прослушивает попытки подключения, используя слушателя onConnect. Ему передаётся соответствующий объект Port.

После того, как обе стороны получили объекты Port, они могут обмениваться сообщениями с помощью Port.postMessage() и Port.onMessage. Когда они закончат, любая сторона может отключиться, используя Port.disconnect(), что сгенерирует событие Port.onDisconnect на другой стороне, позволяя другой стороне выполнить необходимые действия по очистке.

Объект Port также может быть отключён в ответ на различные события. См. Жизненный цикл.

Вы можете использовать эту модель для связи между:

  • разными частями вашего расширения (например, между скриптами контента и фоновыми скриптами)
  • между вашим расширением и приложением с родным кодом, работающим на компьютере пользователя.
  • между вашим расширением и другим расширением

Для различных типов соединений необходимо использовать разные API соединений, как подробно описано в таблице ниже.

Тип соединения Инициация попытки соединения Обработка попытки соединения
Фоновый скрипт к скрипту контента tabs.connect() runtime.onConnect
Скрипт контента к фоновому скрипту runtime.connect() runtime.onConnect
Расширение к приложению с родным кодом runtime.connectNative() Не применимо (см. Родные сообщения).
Расширение к расширению runtime.connect() runtime.onConnectExternal

Тип

Значения этого типа — объекты. Они содержат следующие свойства:

name

string. Имя порта, определенное в вызове runtime.connect() или tabs.connect(), который его создал. Если этот порт подключён к приложению с родным кодом, его имя — имя приложения с родным кодом.

disconnect

function. Отключает порт. Любая сторона может вызвать это, когда закончит работу с портом. Это вызовет onDisconnect на другой стороне. Это полезно, если другая сторона сохраняет какое-либо состояние, связанное с этим портом, которое можно очистить при отключении. Если этот порт подключен к приложению с родным кодом, эта функция закроет приложение с родным кодом.

error

object. Если порт был отключён из-за ошибки, это будет установлено в объект со строковым свойством message, предоставляющим дополнительную информацию об ошибке. См. onDisconnect.

onDisconnect

object. Это содержит функции addListener() и removeListener(), общие для всех событий расширений, созданных с использованием API WebExtension. Функции слушателей будут вызываться, когда другая сторона вызвала Port.disconnect(). Это событие будет вызываться только один раз для каждого порта. Функция слушателя получит объект Port. Если порт был отключён из-за ошибки, аргумент Port будет содержать свойство error, предоставляющее дополнительную информацию об ошибке:

port.onDisconnect.addListener((p) => {
  if (p.error) {
    console.log(`Disconnected due to an error: ${p.error.message}`);
  }
});

Обратите внимание, что в Google Chrome port.error не поддерживается: вместо этого используйте runtime.lastError для получения сообщения об ошибке.

onMessage

object. Это содержит функции addListener() и removeListener(), общие для всех событий расширений, созданных с использованием API WebExtension. Функции слушателей будут вызываться, когда другая сторона отправила этому порту сообщение. Слушатель получит значение, отправленное другой стороной.

postMessage

function. Отправьте сообщение другой стороне. Этот параметр принимает один аргумент, который представляет собой сериализуемое значение (см. Алгоритм клонирования данных), представляющее отправляемое сообщение. Оно будет доставлено любому скрипту, прослушивающему событие порта onMessage или приложению с родным кодом, если этот порт подключён к приложению с родным кодом.

sender Необязательно

runtime.MessageSender. Содержит информацию об отправителе сообщения. Это свойство будет присутствовать только в портах, переданных в слушатели onConnect/onConnectExternal.

Жизненный цикл

Жизненный цикл объекта Port описан в документации Chrome.

Однако существует важное различие между Firefox и Chrome, обусловленное тем, что API runtime.connect и tabs.connect являются каналами широковещательной передачи. Это означает, что потенциально может быть более одного получателя, что приводит к неоднозначности при закрытии одного из контекстов с вызовом runtime.onConnect. В Chrome порт остаётся активным, пока существует любой другой получатель. В Firefox порт закрывается при разгрузке любого из контекстов. Другими словами, условие отключения,

  • Все фреймы, получившие порт (через runtime.onConnect), были разгружены.

которое действует в Chrome, заменяется

  • Любой фрейм, получивший порт (через runtime.onConnect), был разгружен.

в Firefox (см. отчёт об ошибке 1465514).

Совместимость с браузерами

Рабочий стол Мобильные
Chrome Edge Firefox Internet Explorer Opera Safari WebView Android Chrome Android Firefox for Android Opera Android Safari на IOS Samsung Internet
Port 26 15 45 ? 15 14 ? ? 48 ? 15 ?
error Нет Нет 52 ? Нет Нет ? ? 52 ? Нет ?

Примеры

Подключение из скриптов контента

Этот скрипт контента:

  • подключается к фоновому скрипту и сохраняет порт в переменной myPort.
  • прослушивает сообщения на myPort и регистрирует их.
  • отправляет сообщения в фоновый скрипт с помощью myPort, когда пользователь нажимает на документ.
// content-script.js

let myPort = browser.runtime.connect({name:"port-from-cs"});
myPort.postMessage({greeting: "hello from content script"});

myPort.onMessage.addListener((m) => {
  console.log("In content script, received message from background script: ");
  console.log(m.greeting);
});

document.body.addEventListener("click", () => {
  myPort.postMessage({greeting: "they clicked the page!"});
});

Соответствующий фоновый скрипт:

  • прослушивает попытки подключения со стороны скрипта контента.
  • при получении попытки подключения:
    • сохраняет порт в переменной portFromCS.
    • отправляет скрипту контента сообщение через порт.
    • начинает прослушивать сообщения, полученные по порту, и регистрирует их.
  • отправляет сообщения в скрипт контента с помощью portFromCS, когда пользователь нажимает на значок расширения в браузере.
// background-script.js

let portFromCS;

function connected(p) {
  portFromCS = p;
  portFromCS.postMessage({greeting: "hi there content script!"});
  portFromCS.onMessage.addListener((m) => {
    console.log("In background script, received message from content script")
    console.log(m.greeting);
  });
}

browser.runtime.onConnect.addListener(connected);

browser.browserAction.onClicked.addListener(() => {
  portFromCS.postMessage({greeting: "they clicked the button!"});
});

Несколько скриптов контента

Если у вас несколько скриптов контента, которые взаимодействуют одновременно, вы можете сохранить каждое подключение в массиве.

// background-script.js

let ports = []

function connected(p) {
  ports[p.sender.tab.id]    = p
  // …
}

browser.runtime.onConnect.addListener(connected)

browser.browserAction.onClicked.addListener(() => {
  ports.forEach((p) => {
        p.postMessage({greeting: "they clicked the button!"})
    })
});

Подключение к приложениям с родным кодом

В этом примере подключается к приложению с родным кодом "ping_pong" и начинает прослушивать сообщения от него. Также оно отправляет приложению с родным кодом сообщение, когда пользователь нажимает на значок расширения в браузере:

/*
On startup, connect to the "ping_pong" app.
*/
let port = browser.runtime.connectNative("ping_pong");

/*
Listen for messages from the app.
*/
port.onMessage.addListener((response) => {
  console.log(`Received: ${response}`);
});

/*
On a click on the browser action, send the app a message.
*/
browser.browserAction.onClicked.addListener(() => {
  console.log("Sending:  ping");
  port.postMessage("ping");
});

Примечание: Этот API основан на API chrome.runtime Chromium. Данная документация основана на runtime.json кода Chromium.

© 2005–2023 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/Port

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API