【Electron】IPC通信の実装方法

概要

ElectronでDesktopアプリを作る際に使用するIPC通信を実装する方法のまとめ。

IPC通信とは

IPC通信とは「Inter-Process Communication」の略で、プロセス間通信のこと。

Electronではプロセスがアプリ本体を管理しているメインプロセスと 、画面の表示を行うレンダラプロセスの2種類のプロセスで構築されている。

基本的にレンダラプロセスでは画面表示の処理のみをを行う為、OSネイティブな機能等を使用する場合、メインプロセスで実行を行う必要がある為、メインプロセスとレンダラプロセス間の通信が必要となる。

作成する機能

今回はIPC通信を使用し、テキストボックスに入力した文字をメインプロセスに送信し、そのままレンダラプロセスに送り返して、画面に送信した文字を表示する機能を実装する。

環境

項目 情報
OS Windows11
Node js 16.13.2
Electron 17.0.1

実装

Electronプロジェクトの作成

Electronプロジェクトを作成する。

作成する際は下記記事等を参考。

koubou-rei.com

preload.jsの作成

メインプロセスとレンダラプロセスの橋渡し用のファイル preload.jssrcファルダ内に作成する。

const { contextBridge, ipcRenderer } = require("electron");

contextBridge.exposeInMainWorld(
    "api", {
    // レンダラ => メイン
    sendMessage: (message) => {
        ipcRenderer.send("send-message", message);
    },
    // メイン => レンダラ
    onReceiveMessage: (listener) => {
        ipcRenderer.on("receive-message", (event, ...arg) => listener(...arg));
    },
});

メインプロセスを編集

ipcMainをインポート。

const { app, BrowserWindow, ipcMain } = require('electron');

メインプロセスのwebPreferencesに下記を追加。

mainWindow = new BrowserWindow({
        webPreferences: {
            nodeIntegration: false, // 追加
            contextIsolation: true, // 追加
            worldSafeExecuteJavaScript: true,  // 追加
            preload: path.resolve(__dirname, 'preload.js') // 追加
        },
        width: 800, height: 600,
    });

レンダラプロセスからメッセージを受け取った時の処理をを追加。

// レンダラプロセスからのメッセージを受け取る
ipcMain.on("send-message", (event, msg) => {
    // レンダラプロセスへメッセージをそのまま返す
    mainWindow.webContents.send('receive-message', msg);
})

index.htmlを編集

最後に index.htmlを編集し、メッセージ入力用のテキストボックス等を作成する。

<html>

<head>
    <meta charset="UTF-8">
    <title>IPC</title>
</head>

<body>
    <h1>IPC</h1>
    <div>
        <input id="input-msg" type="text" />
        <button id="button-send" onclick="sendMessage">Send</button>
    </div>
    <div>
        ReceiveMassage : <span id="receive-msg"></span>
    </div>
    <script type="text/javascript">
        window.onload = () => {
            document.getElementById("button-send").addEventListener('click', () => {
                var msg = document.getElementById("input-msg").value;
                window.api.sendMessage(msg);
            });
            window.api.onReceiveMessage((msg) => {
                document.getElementById("receive-msg").textContent = msg;
            });
        }
    </script>
</body>

</html>

完成形

f:id:sanpei07:20220222185223g:plain

参考

qiita.com

webbibouroku.com