kosian is here #6

wasavi のフロントエンドとバックエンドとの通信の方式について若干の変更を行いたい。

そのあたりはもちろん kosian 側で抽象化してあるのだが、wasavi はまず Chrome 上で作り始めたので、Chrome のエクステンションにおけるバックグラウンドとコンテントスクリプトの通信の作法をだいたいそのまま持ってきている。

つまり
extension.postMessage(message [, callback])
というメソッドを用いる。この callback がこの記事の主役である。

この callback を指定することにより、投げたメッセージに対する直接の応答を得ることができる。つまり非常に限定されたメッセージリスナとみなすことができる。一方、フロントエンドはコンテントスクリプト毎の汎用メッセージもリスンしていて:
chrome.extension.onRequest.addListener(handleMessage);
こちらは例えば他のタブで動作中の wasavi で設定が変更されたという同期通知や、dropbox(など)からのファイル読み込みの進捗通知などを扱う。

要するに、2 種類のメッセージリスナを扱っている。この状況で、それぞれが扱うメッセージの性格が完全に分離されているのならば、別に 2 種類あることは悪いことではないのだけど。がしかし上記のファイル読み込みの進捗通知というものが、微妙にどっちつかずな存在なのである。

ファイル読み込みは、フロントエンドからバックエンドへパスなどを渡し、バックエンドで認証などを済まし、読み込むためのリクエストを発行し、その結果をフロントエンドへ返す。フロントエンド側で見るとこの処理は ex コマンド [cci]read[/cci] の処理ということになり、そのハンドラの中で完結するはずのものである。が、実際は [cci]read[/cci] コマンド実行中のバックエンドからのメッセージは、汎用メッセージ側で処理している。これはやや不格好だ。

なぜ postMessage() の callback を使わないのかといえば、つまり [cci]read[/cci] 実行中、バックエンドからのメッセージは複数回送信されるからである。callback は 1 度呼び出されて終わりなのだ。これを拡張し、複数回 callback が呼び出される構造にすれば、必要な処理はすべて [cci]read[/cci] ハンドラの中に掛けば済むようになって、収まりがよいはずだ。

というわけでそうした。ここで、ソースの修正は割とすぐに終わったのだけど、実際に Opera 12 で動かしてみるとさっぱり狙った動作をせず、あーでもないこーでもないとした挙句、単に Opera を再起動させたらちゃんと動くようになったというなんとも言えない事件があったのだが、まあ Opera においては特に珍しいことではないので、いいのだ。

Leave a Reply

Your email address will not be published. Required fields are marked *