はじめに
Vite + Vue3 + Electron + PixiJS の組み合わせを前回作りましたが、それをベースに今回はそこからIPC通信を使って、Electronのメインプロセスと、Vue3のレンダラープロセスのデータの送受信を行っていきたいとおもいます
目次
1. 環境
- WebStorm 2023.3.2
- Node 18.18.2
- Vue 3.4.5
- Vite 5.0.11
- PixiJS 7.3.3
- Windows 11 Home
2. electron-vite の通信の考え方
electron-viteサイト > Guide
> Development
> Using Preload Scripts の図を見てみると、基本的には一般的なElectronと同じ構成になっていて、以下の2つのプロセスに分かれます
- Main Process
- Electronの設定やNodeJSなど、サーバ的な役割
- Renderer Process (Browser Window)
- Vue3やPixiJSなどのブラウザ的な役割
IPC通信をするのは、このMain Process
とRenderer Process
> preload.js
が行い、preload.js
はcontextBridge
を使って、Renderer Process
内のスクリプトにデータを送ります
3. send / on を使った送受信
IPC通信でのデータの送受信には、send
とon
が使えます
3-1. Renderer Process -> Main Process
まずは、ブラウザ側からElectron側にデータを送ります
Renderer Process(ブラウザ)側
<script setup lang="ts">
import PixiComponent from './components/PixiComponent.vue'
import { onMounted } from 'vue'
onMounted(() => {
window.electron.ipcRenderer.send('call-main',{message:'call'}) /* Main Process に送信 */
})
</script>
Main Process(Electron)側
import { app, shell, BrowserWindow, ipcMain} from 'electron' //<-- ipcMainを追加
/* 省略 */
ipcMain.on('call-main',(_e,args) => {
console.log(args.message) //<-- callと表示されます
})
3-2. Main Process -> Renderer Process
次に、Electron側からブラウザ側にデータを送ります
Main Process(Electron)側
let mainWindow: BrowserWindow //<-- 他の関数でもアクセスできるように定義
function createWindow(): void {
mainWindow = new BrowserWindow({...} //<-- constを外します
}
/* 省略 */
ipcMain.on('call-main',(_e,args) => {
console.log(args.message)
mainWindow.webContents.send('response-renderer', { message: 'response' }) /* Renderer Process に送信 */
})
Renderer Process(ブラウザ)側
<script setup lang="ts">
import PixiComponent from './components/PixiComponent.vue'
import { onMounted } from 'vue'
onMounted(() => {
window.electron.ipcRenderer.on('response-renderer', (_e, args) => {
console.log(args.message) /* responseと表示されます */
})
window.electron.ipcRenderer.send('call-main', { message:'call' })
})
</script>
send / on
でのデータの送受信の書き方は、Main Process
、Renderer Process
ともに、基本的な書き方は同じです
4. invoke / handle を使った送受信
先ほどのsend / on
でのデータの送受信以外に、invoke / handle
を使った書き方があります
4-1. Renderer Process -> Main Process
ブラウザ側からElectron側にデータを送ります
Renderer Process(ブラウザ)側
<script setup lang="ts">
import PixiComponent from './components/PixiComponent.vue'
import { onMounted } from 'vue'
onMounted( async () => { //asyncを追加します
await window.electron.ipcRenderer.invoke('call-main',{message:'call'}) /* Main Process に送信 */
})
</script>
Main Process(Electron)側
import { app, shell, BrowserWindow, ipcMain} from 'electron' //<-- ipcMainを追加
/* 省略 */
ipcMain.handle('call-main',(_e,args) => {
console.log(args.message) //<-- callと表示されます
})
4-2. Main Process -> Renderer Process
Main Process(Electron)側
import { app, shell, BrowserWindow, ipcMain} from 'electron'
/* 省略 */
ipcMain.handle('call-main',(_e,args) => {
console.log(args.message)
return { message: 'response' } //<-- Renderer Processに送信
})
Renderer Process(ブラウザ)側
<script setup lang="ts">
import PixiComponent from './components/PixiComponent.vue'
import { onMounted } from 'vue'
onMounted( async () => {
const result = await window.electron.ipcRenderer.invoke('call-main',{message:'call'}) /* result に戻り値を受け取る */
console.log(result.message) /* response と表示されます */
})
</script>