ElectronのBrowserWindow間で直接メッセージをやりとりする
最近、社内でLT(https://labs.gree.jp/blog/2018/10/17291/)があって、そこで話をしたので、その時の内容を書く。
これは、その一部の話。
経緯とか要約とか
複数立ち上げたBrowserWindowのインスタンス間でメッセージをやりとりする。
社内のメモで出来ない。いったん、main processを経由しないといけない、と書いている人が居たので、
ちょっと書いたのであった。
説明
ウィンドウ間でメッセージをやりとりするには、
main processをいったん経由してから、
他のrenderer processにメッセージを送るのが作法のような気がするが
どうにかして、BrowserWindowのインスタンスを取得すれば、
各ウィンドウ間で直接データをやりとりできる。
具体的な実装の例
- BrowserWindowのインスタンスを作る箇所
// https://github.com/taku-o/hello-electron-003-to-sub-msg/blob/master/electron.ts mainWindow = new BrowserWindow({ width: 600, height: 600, acceptFirstMouse: true, show: true }); mainWindow.loadURL(`file://${__dirname}/main.html`); // !!!! global.mainWindow = mainWindow;
- メッセージを投げる側の例
// https://github.com/taku-o/hello-electron-003-to-sub-msg/blob/master/js/main.ts $scope.sendMsgTo1stWindow = function() { // remoteは参照そのものではなく、呼んだ瞬間のコピーのような const firstWindow = require(‘electron').remote.getGlobal('firstWindow'); firstWindow.webContents.send('message', 'message from main.'); };
- メッセージを受ける側の例
// https://github.com/taku-o/hello-electron-003-to-sub-msg/blob/master/js/second.ts var ipcRenderer = require('electron').ipcRenderer; // recieve message $scope.message = ''; ipcRenderer.on('message', (event, message: string) => { $scope.message = message; $timeout(() => { $scope.$apply(); }); });
こんなに短いサンプルコードなのに、angularやtypescript使っていてわかりにくいとか、
global使うのは反則ではないのか?
とかあるかもしれないけど、あまり細かいことは気にしないで欲しい。
"できる"と"やる"は別の話
でも、結局は、main processで、BrowserWindowのインスタンスを管理することになると思います。
だいたい設計的な理由で。その方がいろいろ利点があるはず。