【Chrome拡張機能】チャンネルを使った相互通信 

satoshiii
satoshiii

対象読者

  • Chromeの拡張機能について知りたい方
  • バックグランド、ブラウザアクションなどの相互でメッセージをやりとりする方法が知りたい方

チャンネルとは?

チャンネルを使うと、永続的な通信を行うことができるようになります。

チャンネル以外のメッセージを送信する仕組みはこちらの記事参照

【Chrome拡張機能】メッセージパッシング(バックグランドページ→ブラウザアクション) 【Chrome拡張機能】メッセージパッシング(ブラウザアクション→バックグランドページ)

サンプルと動作確認

拡張機能のアイコンをタップすると、ブラウザアクション側の処理でjsを読み込みアラートを表示します

裏では、ブラウザアクション側からバックグランド側へメッセージを送信します。

バックグランド側でメッセージを受信し、受信した旨のメッセージをアラートで表示します。

裏でバックグランド側からブラウザアクションに対して応答メッセージを送信します。

ブラウザアクション側で、応答メッセージを受信しアラートを表示します。

コードと解説

チャンネルを使うことで、メッセージの送受信を相互に送ることができます。

マニフェストファイル

{
  "manifest_version":2,
  "name":"Chrome ex page action",
  "version":"1",
  "background": {
    "scripts": ["background.js"],
    "persistent": false
  },
  "browser_action": {
    "default_popup": "popup.html",
    "default_title": "Helloを表示"
  }
}


backgroundやbrowser_actionなどは別記事を参考に

Chrome拡張ブラウザアクション【Chrome拡張機能】ブラウザアクション 【Chrome拡張機能】バックグランドページ

HTMLファイル

<!DOCTYPE html>
<meta charset="UTF-8" />
<html>
<head>
    <title></title>
    <script type="text/javascript" src="myscript.js"></script>
</head>

<body>

<p id="hello">Hello!</p>

</body>
</html>

myscript.jsファイルの読み込み

JavaScriptファイル

let port = chrome.runtime.connect({name: "TestChannel"});
console.log('myscript読み込み')
alert('メッセージを送信します')
port.postMessage({msMessage: "メッセージ送信"});

port.onMessage.addListener(function(msg) {
    console.log(msg.answerMsg);
    alert(msg.answerMsg)
});

chrome.runtime.connect

このメソッドでチャンネルを登録しています。

nameはチャンネル名、なので今回は「TestChannel」で登録しています。

port.postMessage({msMessage: “メッセージ送信”});

portは変数名です。上記のチャンネル登録した中身を格納しています。

この変数からpostMessageメソッドを呼び出すことで、メッセージを送信しています。

今回は、「メッセージ送信」というメッセージを送信しています。

port.onMessage.addListener

送信先からの応答メッセージを受信するイベントリスナーの登録を行なっています。

port変数に対応するメッセージを受信します。

今回は、後述するbackground.js側からの応答した結果をアラートで表示するようにしています。

console.log('back start')
chrome.runtime.onConnect.addListener(function(port) {
    if(port.name == "TestChannel"){
        port.onMessage.addListener(function(msg) {
            console.log('受信')
            if(msg.msMessage == "メッセージ送信"){
                alert('メッセージを受信しました')
                port.postMessage({answerMsg: "メッセージ受信完了"});
            }
        });
    }
});

chrome.runtime.onConnect.addListener

メッセージを受信するイベントリスナーを登録しています。

*myscript側のaddListenerとは別物ですので注意!

if文の中で、port.nameが”TestChannel”だったら中身の処理をするようになっています。

port.onMessage.addListener

チャンネルから送信した内容を受信しています。

一応、if文の中で送信されたメッセージが正しいかの判定処理を入れています。

正しければ、「メッセージを受信しました」とアラートを表示しています。

その後、port.postMessageで応答メッセージを送っています。

なので、myscript側で、応答メッセージである「メッセージ受信完了」がアラートで表示されます。

注意ポイント

頻繁に呼び出してしまうと、バックグランド側イベントページが常に起動状態となってしまうためメモリ解放が行われなくなってしまいます

そのため、あまりに頻繁にデータの送受信をする必要があるのであればチャンネルやsendMessageなどのメッセージパッシングを使わない別の方法も検討する必要があります。

メッセージパッシングを使わない方法としては、storageを使うという方法もあります。

【Chrome拡張機能】ストレージを使ったデータの扱い

まとめ

satoshiii
satoshiii

チャンネルと使うと、sendMessageやonMessageのように一方通行ではなく

相互にメッセージを送受信することができるようになります。

ただし、使い方を誤るとイベントページのメリットであるメモリ解放を阻害したりしますので要注意です!

ソースコードはこちら

https://github.com/satoNobu/chrome_ex/tree/channel

他の拡張機能についてはこちらの記事参照

Chrome【Chromeの拡張機能】開発 まとめ

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です