Electron 进程间通信

Electron 桌面应用有两个进程,分别为主进程和渲染进程。

一、主进程和渲染进程介绍

主进程(Main Process)

  • 应用启动时,会创建个主进程
  • 一个应用有且只有一个主进程
  • 只有主进程可以进行 GUI 的 API 操作,即调用 Native APIs

渲染进程(Renderer Process)

  • Windows 中展示的界面通过渲染进程表现,DOM 操作,node js
  • 一个应用可以有多个渲染进程
  • 要通过主进程才可以访问原生 API(Native APIs),要先跟主进程进行 ipc 通信

二、渲染进程发消息给主进程

其实主要就是两个 API 的使用: 渲染进程里的 ipcRenderer 与 主进程里的 ipcMain

渲染进程发异步消息给主进程

// 渲染进程脚本
const { ipcRenderer } = require('electron')
// 发送异步消息
btns[0].addEventListener('click', () => {
    ipcRenderer.send('msg1', '这是一条来自于异步的消息')
})
// 监听消息
ipcRenderer.on('msg1Re', (ev, data) => {
    console.info(data)
})
// 主进程脚本
const { ipcMain } = require('electron')
ipcMain.on('msg1', (ev, data) => {
    console.info(data)
    // 发送消息给渲染进程
    ev.sender.send('msg1Re', '这是一条来自主进程的反馈消息')
})

渲染进程发同步消息给主进程

// 渲染进程脚本
const { ipcRenderer } = require('electron')
// 发送同步消息
btns[1].addEventListener('click', () => {
    const result = ipcRenderer.sendSync('msg2', '这是一条来自于同步的消息')
    console.info(result)
})
// 主进程脚本
const { ipcMain } = require('electron')
ipcMain.on('msg2', (ev, data) => {
    console.info(data)
    // 反馈消息
    ev.returnValue = '这是一条来自主进程的同步反馈消息'
})

三、主进程发消息给渲染进程

// 主线程脚本
BrowserWindow.getFocusedWindow().webContents.send(
    'mtp',
    '主进程发送消息给渲染进程'
)
// 渲染进程脚本
ipcRenderer.on('mtp', (ev, data) => {
    console.info(data)
})

四、渲染进程间通信

基于本地存储的渲染进程间通信

即采用 localStorage 机制

借助主进程,进行不同渲染进程间的通信

// 发起消息的渲染进程
ipcRenderer.send('mti', '这是条来自于 modal 的消息')
// 主进程
ipcMain.on('mti', (ev, data) => {
    // 通过 id 获取到对应的渲染进程,然后消息传递
    BrowserWindow.fromId(mainId).webContents.send('mti2', data)
})
// 接收消息的渲染进程 
ipcRenderer.on('mti2', (ev, data) => {
	console.info(data)
})

使用 sendTo

前提是要知道另一渲染窗口的 webContents 对应的 id
这边采用 global 存储窗口 ID

  const modalMain = new BrowserWindow({
  	width: 200,
	height: 200,
	parent: BrowserWindow.fromId(mainId), // 这样关闭父窗口,则子窗口会一并关闭
	webPreferences: {
		nodeIntegration: true,
		contextIsolation: false
	}
  })
  global.sharedObject =  {
    modalMainWebContentsId: modalMain.webContents.id
  }

然后在渲染进程里通过 getGlobal 来获取该 ID 值,并通过 sendTo 来发送消息

let sharedObject = getGlobal('sharedObject') 
let modalMainWebContentsId = sharedObject.modalMainWebContentsId
ipcRenderer.sendTo(modalMainWebContentsId, 'do-some-work', 1)

这样其他渲染进程就通过监听 do-some-work 来获取消息

ipcRenderer.on('do-some-work', (e, data) => {
    console.info(data)
  })

五、remote

GUI 相关的模块 (如 dialog、menu 等) 仅在主进程中可用, 在渲染进程中不可用。为了在渲染进程中使用它们, 必须使用 remote 模块。这样就可以调用 main 进程的方法,而不用显示发送进程间的信息。

不同的 Electron 版本,remote 获取方式不同。
比如在渲染进程里创建个窗口:
In electron > 14.0.0:

  1. 安装 @electron/remote
  2. 定义 webPreferences 属性
webPreferences: {
    nodeIntegration: true, // 配合 contextIsolation 才会起作用, 使得渲染进程可以使用 node API
    contextIsolation: false
}
  1. 主进程脚本:
require('@electron/remote/main').initialize()
mainWindow.loadFile('index.html')
const contents = mainWindow.webContents
require('@electron/remote/main').enable(contents)
  1. 子进程脚本
const { BrowserWindow } = require('@electron/remote')

In electron == 14.0.0:
参照官文:https://www.electronjs.org/docs/breaking-changes#%E5%B7%B2%E5%BA%9F%E5%BC%83%EF%BC%9A-remote-%E6%A8%A1%E5%9D%97
实际上就是不用在主进程里 enable webContents
In electron < 14.0.0:

  1. 主进程脚本:
{ webPreferences: { enableRemoteModule: true } }
  1. 渲染进程脚本
const { BrowserWindow } = require('electron').remote
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值