Skip to content

进程间通信

前言

通信主要是主进程和渲染进程间的通信。由于安全性,渲染进程不能直接调用主进程的API,所以需要通过preload模块搭一个桥梁进行通信。

渲染器进程到主进程(单向)

在Preload中使用ipcRenderer.send API发送消息,在主进程中使用ipcMain.on接收。

javascript

// proload.js
const  { contextBridge, ipcRenderer } = require('electron');
contextBridge.exposeInMainWorld('electronApi', {
    setTitle: (title) => ipcRenderer.send('set-title', title)
});

// renderer.js
const setButton = document.getElementById('btn')
const titleInput = document.getElementById('title')
setButton.addEventListener('click', () => {
    const title = titleInput.value
    window.electronAPI.setTitle(title)
});

// main.js
ipcMain.on('set-title', (event, title) => {
    const webContents = event.sender;
    const win = BrowserWindow.fromWebContents(webContents);
    win.setTitle(title)
})

渲染器进程到主进程(双向)

主要场景是渲染进程调用主进程模块并等待结果。这可以通过将ipcRenderer.invoke与ipcMain.handle搭配使用来完成。

javascript
// proload.js
// 这里返回一个Promise,且内容是handle回调返回的内容
const ret = ipcRenderer.invoke('openDialog')
ret.then((result) => {
    console.log(result) // test 111
})

// main.js
ipcMain.handle('openDialog', () => {
    return 'test 111'
})

主进程到渲染进程

由于渲染器可能存在在多个,所以需要知道将消息发送到哪个渲染器。消息主要是通过WebContents实例的send方法,使用方法和ipcRenderer.send相同。

javascript
// proload.js
// 这里返回一个Promise,且内容是handle回调返回的内容
ipcRenderer.on('updateValue', (event, value) => {
    console.log(value)  // 111
    event.sender.send('returnUpdate', value + ': is updated')
})

// main.js
// mainWindow是窗口实例引用
mainWindow.webContents.send('updateValue', 111)
ipcMain.on('returnUpdate', (event, value) => {
    console.log(value) // 111: is updated
})

渲染器到渲染器

没有直接方法通信,只能通过间接通信。

  • 通过主进程作代码通信。
  • 从主进程将一个MessagePort传递到两个渲染器。