LoginSignup
121
122

More than 5 years have passed since last update.

Electronでipcを使ってプロセス間通信を行う

Posted at

概要

Electron(旧称atom-shell)には起動時に立ち上がるJavaScript側のプロセス(メインプロセス)と、メインプロセスから立ち上げるBrowserWindowのプロセス(レンダラプロセス)が存在する。メインプロセスとレンダラプロセスは別物なので、これらの間で状態を伝達する仕組みが必要になることがある。ElectronにもIPC(プロセス間通信)の仕組みは存在し、ずばりipcモジュールとして定義されている。

前提

BrowserWindow(レンダラプロセス)を立ち上げてHTMLを表示する部分までは終了しているものとする。

var app = require('app');
var BrowserWindow = require('browser-window');

app.on('ready', function() {
  var currentWindow = new BrowserWindow({});
  currentWindow.loadUrl('file://' + __dirname + '/index.html');
});

だいたいこれぐらいの環境を想定。

ipcを使う

レンダラプロセス(送信側)

var ipc = require('ipc');

// 非同期
ipc.send('asynchronous-message', 'ping');

// 同期
var response = ipc.sendSync('synchronous-message', 'ping');

sendSyncを使えば即座にメインプロセスからのレスポンスが取れるが、レスポンスを返すまでレンダラプロセスがブロックされるので、利用は非推奨となっている。

メインプロセス(受信側)

var ipc = require('ipc');

// 非同期
ipc.on('asynchronous-message', function(event, arg) {
  event.sender.send('asynchronous-reply', 'pong');  // 送信元へレスポンスを返す
});

// 同期
ipc.on('synchronous-message', function(event, arg) {
  event.returnValue = 'pong';  // 送信元へレスポンスを返す
});

ipcモジュールの実態はEventEmitterなので、同期非同期に関わらずonで受けられる。送信は非同期だったのに同期でレスポンスを返してしまった場合は、無効なレスポンスとして無視される。同期で送信して非同期でレスポンスを返した場合は、処理の終了を待った上で非同期レスポンスとして処理される。

非同期レスポンスはレンダラプロセスにてonで指定すれば受けられる。

WebContents.send

メインプロセスからレンダラプロセスへ送信を行う場合、WebContents.sendで送ることができる。

current.webContents.on('did-finish-load', function() {
  current.webContents.send('asynchronous-message', 'ping');
});

同期通信はデッドロックが発生しやすいという理由により存在しない。内部的にはipcの呼び出しなので、レンダラプロセスにおけるipcのレスポンス処理と同様に、onで指定することにより受けられる。

このときレンダラプロセスでJavaScriptの実行が完了していないと、コールバックが登録されていないことになり、コールバックが意図したとおりに発火しないことに注意しなければならない。そのため、did-finish-loadイベントにコールバックを登録し、レンダラプロセスにおけるJavaScriptの実行が完了するまで待つなどの工夫が必要になる。

121
122
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
121
122