Chrome扩展程序本地消息同步

3

我在Windows上遇到了本地消息同步的问题。我正在尝试在backgroundPage和hostApp之间同步消息。通常,我们使用本地消息传递如下:

//popup.js
function appendMessage(text) {
  document.getElementById('response').innerHTML += "<p>" + text + "</p>";
}

function sendNativeMessage() {
  message = {"command": document.getElementById('input-text').value};
  port.postMessage(message);
  appendMessage("Sent message: <b>" + JSON.stringify(message) + "</b>");
}
function onNativeMessage(message) {
  appendMessage("Received message: <b>" + JSON.stringify(message) + "</b>");
}

function onDisconnected() {
  appendMessage("Failed to connect: " + chrome.runtime.lastError.message);
  port = null;
  updateUiState();
}

function connect() {
  var hostName = "com.google.chrome.example.dmtest1";
  appendMessage("Connecting to native messaging host <b>" + hostName + "</b>");
  port = chrome.runtime.connectNative(hostName);
  port.onMessage.addListener(onNativeMessage);
  port.onDisconnect.addListener(onDisconnected);
  updateUiState();
}

document.addEventListener('DOMContentLoaded', function () {
  document.getElementById('connect-button').addEventListener(
      'click', connect);
  document.getElementById('send-message-button').addEventListener(
      'click', sendNativeMessage);
  updateUiState();
});


<html>
  <head>
    <script src='./popup.js'></script>
  </head>
  <body>
    <button id='connect-button'>Connect</button>
    <input id='input-text' type='text' />
    <button id='send-message-button'>Send</button>
    <div id='response'></div>
  </body>
</html>

但 sendNativeMessage() 和 onNativeMessage(..) 函数是异步的,我想让它们变成同步的。我尝试了下面的方法,但无法从主机(C++ exe)获取响应数据,并且导致 Chrome 崩溃。

function sendNativeMessage() {
  var message = {"command": document.getElementById('input-text').value};
  port.postMessage(message);
  appendMessage("Sent message: <b>" + JSON.stringify(message) + "</b>");

  port.onMessage.addListener(function(msg) { 
    appendMessage("Receive message: <b>" + JSON.stringify(msg) + "</b>");
  });
}

我该如何做到这一点,是否可能,有什么帮助吗?


函数 port.sendMessage 是否存在? - SevenWow
为什么你想要它们同步?你必须记住,在函数执行期间,UI 将不会更新...如果调用需要一些时间,那么你的页面将会冻结。但这并不是不可能做到的。 - Emrys Myrooin
感谢您的回复@EmrysMyrooin,我在page1.html页面上有一个按钮,当我点击它时,它会向内容脚本发送消息。然后内容脚本将消息发送到扩展程序的后台页面,扩展程序将数据发送到主机并获取一些数据,最终将显示在page1.html上。我希望在完成按钮点击操作后立即在page1.html上显示数据,你能帮我实现吗? - SevenWow
好的。那么你为什么想要它同步?你可以指定一个回调函数,在你想要发送数据回内容脚本时调用它。 - Emrys Myrooin
我明白你想要什么。但这不是一个“好”的做法。如果你愿意,可以在JavaScript中寻找Promise,它允许你定义在异步调用后要执行的操作,并且代码看起来更加优美。 - Emrys Myrooin
显示剩余11条评论
1个回答

4

经过几天的搜索和测试,我终于找到了一个答案(链接在此:如何在本地应用程序中处理chrome.runtime.sendNativeMessage()),并解决了我的问题。我放弃了使我的回调函数同步的想法,我只是使用另一种方式在Chrome扩展程序背景页和我的本地主机应用程序之间进行通信。我使用下面的代码来发送和接收backpage和hostapp之间的数据,并且它是同步的:

chrome.runtime.sendNativeMessage(hostName, sendMsg, function(response) {
            if (chrome.runtime.lastError) {
                alert("ERROR: " + chrome.runtime.lastError.message);
            } else {
                sendResponse({farewell: ParseJSON(response)});
            }
        });

请问您能否将代码片段标签从您的问题和答案中删除?它们仅用于自包含的HTML/JS示例(如JSFiddle),当然无法运行扩展代码。 - Xan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接