electronでMain/Renderer間で通信するときに毎回作りたいクラス


プロセス間通信の基本

Main 受信


import { ipcMain } from 'electron'
ipcMain.on(key, (event, data) => {
})

Main 送信

import { BrowserWindow } from 'electron'
let mainWindow = new BrowserWindow({
    height: 563,
    useContentSize: true,
    width: 1500,
    icon: __dirname + '../../icons/mac/app.icns',
    webPreferences: {
      webSecurity: false
    }
  })
mainWindow.webContents.send(key);

Renderer 送信・受信

import { ipcRenderer } from 'electron'
ipcRequest (key: string, data: any) : Promise<any>{
      return new Promise( resolve => {
        ipcRenderer.send(key, data)
        ipcRenderer.on(key, (_, data) => {
          console.log('ipcRequest', data)
        })  
      })
    },

IPCをAPIのように使う

Renderer にmixinで関数を生やす

aync/awaitを使って、送信・受信して結果を受け取れるようにする。

mixin.ts
import { ipcRenderer } from 'electron'
import * as Keys from '../ipcKeys'

export const Mixin = {
  methods: {
    ipcRequest (key: string, data: any) : Promise<any>{
      return new Promise( resolve => {
        ipcRenderer.send(key, data)
        ipcRenderer.on(key, (_, data) => {
          resolve(data)
          console.log('ipcRequest', data)
        })  
      })
    },
    // this.setting = await this.fetchSetting() こんな感じで呼ぶ
    async fetchSetting () {
      let result = await this.ipcRequest(Keys.IPC_KEY_FETCH_SETTING, null)
      return result
    }
  }
}

共通 Key管理

送信にも受信にも同じキーが必要なので管理するクラスを用意しましょう

ipcKeys.ts
export const IPC_KEY_FETCH_ENCODE_FILES = "IPC_KEY_FETCH_ENCODE_FILES"

Main 受信・送信

ipcMonitor.ts
import { EventEmitter } from "events"
import { ipcMain } from 'electron'
import * as Keys from '../../ipcKeys'

export default class IpcMonitor extends EventEmitter {

  constructor(){
    super()
    this.monitor()
  }

  private monitor() {
    ipcMain.on(Keys.IPC_KEY_FETCH_SETTING, (event, _) => {
      this.emit(Keys.IPC_KEY_FETCH_SETTING)
    })
  }
}

呼び出し

  ipcMonitor.on(Keys.IPC_KEY_FETCH_SETTING , async () => {
    const setting = await fileMonitor.fetchSetting()
    mainWindow.webContents.send(Keys.IPC_KEY_FETCH_SETTING, setting);
  })

ただ注意として コールされて実行されるわけじゃないので、不用意にwebContents.sendだけ読んじゃう意図せず受信しちゃうことがある。データの更新などは共通で監視したほうがいいかも。

なぜこんなものが必要な

Main Processからじゃないと呼べないいくつかのメソッドがある。

  • メディアをダウンロードする
  • ffmpegでエンコードする
  • 設定ファイルを保存したりする
  • fsやfsextraを使いたい
  • webじゃできないローカルのフォルダの絶対パスを取得する

などなど。その結果を渡すのを同期的にやる必要がある。