Расширение Chrome - приоритетный обмен сообщениями - PullRequest
0 голосов
/ 04 января 2019

Я разрабатываю расширение chrome, которое использует API-интерфейс chrome времени выполнения для отправки одноразовых сообщений назад и вперед между расширением и страницами, в которые вставляется скрипт содержимого. Проблема в том, что мне нужны некоторые сообщения, чтобы иметь приоритет в этой системе. Я реализовал пользовательский порт для передачи сообщений о приоритетах, однако не могу воспроизвести API sendResponse с решением для порта.

Поток

Клиент вызывает метод, который возвращает обещание, в котором хранится одноразовый номер для метода запроса и разрешения, отправляет сообщение своему родителю через parent.postMessage({data}, '*'), а затем разрешает его, когда прослушиватель window s message вызывается с данные, содержащие одноразовый номер.

Скрипт содержимого расширения прослушивает сообщения:

const port = chrome.runtime.connect({name: 'priorityPort'})
function getResponse(data) {
  return new Promise((resolve, reject) => {
    if (priority) {
      port.postMessage({data})
      port.onMessage.addListener(msg => {
        resolve(msg)
      })
    } else {
      chrome.runtime.sendMessage({data}, resolve)
    }
  })
}

window.addEventListener('message', async event => {
  const response = await getResponse(event.data)
  event.source.postMessage({response})
})

и тогда фоновая страница выступает в качестве другой стороны соединения

// normal
chrome.runtime.onMessage.addListener((obj, sender, sendResponse: data => {
  ;(async () => {
    sendResponse({ status: 'success', body })
  })()
  return true
})
// priority
chrome.runtime.onConnect.addListener((port) => {
  ;(async () => {
    port.onMessage.addListener(async msg => {
      port.postMessage({ status: 'successs', body })
    })
  })()
  return true
})

Однако, это не возвращает ответ запрашивающей стороне, как sendResponse. Любая помощь очень ценится.

1 Ответ

0 голосов
/ 04 января 2019

Вы можете создать очередь, что-то вроде этого:

class Queue {
 constructor() {
   this.arr = [];
   this.awaiting = [];
 }

 enqueue(msg) {
   if (this.awaiting.length) {
     this.awaiting.shift()(msg)
   }else {
     this.arr.push(msg)
   }
 }
   
 dequeue() {
   if (this.arr.length) {
     return this.arr.shift()
   }
   return new Promise(resolve => {
     this.awaiting.push(resolve);
   }); 
 }
}

и вот как вы его используете:

const queue = new Queue();
const port = chrome.runtime.connect({name: 'priorityPort'})

port.onMessage.addListener(msg => {
  queue.enqueue(msg);
})


window.addEventListener('message', async event => {
  port.postMessage({date: event.data})
  const response = await queue.dequeue()
  event.source.postMessage({response})
})

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

Это всего лишь идея, я не совсем уверен, что вы пытаетесь сделать, я, вероятно, сделал этот путь сложным для вашего случая использования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...