
対象読者
- 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などは別記事を参考に


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を使うという方法もあります。


チャンネルと使うと、sendMessageやonMessageのように一方通行ではなく
相互にメッセージを送受信することができるようになります。
ただし、使い方を誤るとイベントページのメリットであるメモリ解放を阻害したりしますので要注意です!
ソースコードはこちら
https://github.com/satoNobu/chrome_ex/tree/channel
他の拡張機能についてはこちらの記事参照
