Google chrome extension ClojureScript中Chrome扩展内的消息传递

Google chrome extension ClojureScript中Chrome扩展内的消息传递,google-chrome-extension,clojurescript,Google Chrome Extension,Clojurescript,我正在尝试编写一个Chrome扩展,在内容脚本和背景页面之间进行一些基本的通信 在Javascript中,我会在内容页和背景页中注册侦听器,例如在背景页中: chrome.browserAction.onClicked.addListener(function(tab) { // Send a message to the active tab chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {

我正在尝试编写一个Chrome扩展,在内容脚本和背景页面之间进行一些基本的通信

在Javascript中,我会在内容页和背景页中注册侦听器,例如在背景页中:

chrome.browserAction.onClicked.addListener(function(tab) {
  // Send a message to the active tab
  chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
    var activeTab = tabs[0];
    chrome.tabs.sendMessage(activeTab.id, {"message": "clicked_browser_action"});
  });
});
(摘自)

另一个在Javascript中工作的示例:

// content.js
chrome.runtime.sendMessage({screenShot: true}, function(response) {
  console.log("response: " + response);
});

// background.js
chrome.runtime.onMessage.addListener(
  function(request, sender, sendResponse) {
    alert('message received!');
    console.log("request: " + request);
    if (request.screenShot) {
      // do something
    }
});
如何将上述代码翻译成ClojureScript

我的第一次尝试是基于模板创建一个项目,并使用的
runtime/connect
方法依赖于核心异步。但是我没有在
content.cljs
background.cljs
脚本之间进行适当的沟通。在
content.cljs
中,我有:

(defn init []
  (go
    (let [bg (runtime/connect)]
      (console/log "content script test")
      (while true
        (>! bg :lol-i-am-a-content-script)
        (console/log "Background said: " (<! bg))))))
(defn init[] (在连接侦听器上)

在Chrome控制台中,我只收到“Background said:fml-i-am-the-Background-script”消息,因此,只有通过后台发送到内容页的消息,反之亦然(我也希望“content script said:lol-i-am-a-content-script”

很可能我在这里犯了一些明显的错误。有人能帮忙吗


谢谢

两周前,我开始在ClojureScript中开发chrome扩展。我开始使用Khroma,我在使用他们的库实现我的背景页面和内容脚本(或我的背景页面和弹出按钮页面)之间的双向通信方面没有问题。所以我可以确认图书馆的工作。不幸的是,我在这里的代码示例中没有看到任何明显的错误

作为旁注:我不喜欢Khorma“滥用”code.async通道来实现双工通信。Khroma在连接时为您提供类似通道的对象。通过在上面放一条信息,你就可以发送信息,通过从中获取信息,你就可以等待接收信息。容易的?但这并不是真正的core.async通道契约。通常在core.async中,放取操作在同一队列上,任何人(生产者或消费者)都可以完成。Khroma实际上把它变成了一个“通道”,里面有两个队列。一个用于发送,一个用于接收。若你们把某物放在频道上,你们就不能把它取回(例如)。一开始我真的很困惑。我想这也让你困惑,像这样的代码很难读懂:

(let [content (<! channel)]
      (console/log "Content script said: " (<! content))
      (>! content :fml-i-am-the-background-script))
(让[content(!content:fml-i-am-the-background-script))
问题是>!它从不阻塞(在Khroma的情况下,put意味着发送,这是一个非阻塞函数调用,与通道无关) 所以我决定写我自己的库来替换Khroma。不仅是为了修复这个小的设计缺陷,主要是因为我想从chromium源代码自动生成库,所以它自动覆盖所有API

该库名为Chromex,我刚刚发布了一个简单的Chrome扩展示例项目以及一些文档:

背景页面的代码如下所示:


请注意,我还将
runtime.Port
包装为类似core.async的通道,但我不会假装双向通信。您只能从通道中获取!来接收消息(通道包装器仅实现core async/ReadPort协议)。若要发布消息,您必须使用单独的
发布消息!
协议方法。

您能显示任何尝试以及失败的原因吗?@Xan-扩展了我原来的问题。谢谢!谢谢您的回答。我正在学习您的示例。
(let [content (<! channel)]
      (console/log "Content script said: " (<! content))
      (>! content :fml-i-am-the-background-script))