使用 Electron 在两个进程 (主进程和渲染进程) 之间进行通讯

此系列文章的应用示例已发布于 GitHub: electron-api-demos-Zh_CN. 可以 Clone 或下载后运行查看. 欢迎 Star .

原文地址:https://segmentfault.com/a/1190000011507250

通过 ipc(进程间通信)模块允许您在主进程和渲染进程之间发送和接收同步和异步消息.

这个模块有一个版本可用于这两个进程: ipcMain 和 ipcRenderer.

在浏览器中查看 main process 和 renderer proces 的完整 API 文档.

异步消息

支持: Win, macOS, Linux | 进程: Both

使用 ipc 以异步方式在进程之间发送消息是首选方法, 因为它会在完成时返回, 而不会阻止同一进程中的其他操作.

此示例将从此进程(渲染器)发送异步消息 "Ping" 到主进程, 然后主进程回答 "Pong".

渲染器进程

const ipc = require('electron').ipcRenderer

const asyncMsgBtn = document.getElementById('async-msg')

asyncMsgBtn.addEventListener('click', function () {
  ipc.send('asynchronous-message', 'ping')
})

ipc.on('asynchronous-reply', function (event, arg) {
  const message = `异步消息回复: ${arg}`
  document.getElementById('async-reply').innerHTML = message
})

主进程

const ipc = require('electron').ipcMain

ipc.on('asynchronous-message', function (event, arg) {
  event.sender.send('asynchronous-reply', 'pong')
})

同步消息

支持: Win, macOS, Linux | 进程: Both

您可以使用 ipc 模块在进程之间发送同步消息. 但请注意, 此方法的同步特性意味着它在完成任务时会阻止其他操作.

此示例将从此进程(渲染器)发送同步消息 "Ping" 到主进程, 然后主进程回答 "Pong".

渲染器进程

const ipc = require('electron').ipcRenderer

const syncMsgBtn = document.getElementById('sync-msg')

syncMsgBtn.addEventListener('click', function () {
  const reply = ipc.sendSync('synchronous-message', 'ping')
  const message = `同步消息回复: ${reply}`
  document.getElementById('sync-reply').innerHTML = message
})

主进程

const ipc = require('electron').ipcMain

ipc.on('synchronous-message', function (event, arg) {
  event.returnValue = 'pong'
})

与隐藏窗口通信

支持: Win, macOS, Linux | 进程: Both

通常的做法是创建一个新的不可见浏览器窗口(渲染器进程), 以便在不影响主应用程序窗口中的性能的情况下运行任务.

在这个示例中, 我们使用 remote 模块从这个渲染器进程创建一个新的不可见的浏览器窗口. 当新页面加载时, 我们用 ipc 发送一个消息给正在监听的新窗口.

然后新窗口计算阶乘并发送要由此接收的结果到原始窗口并添加到上面的页面中.

渲染器进程

const BrowserWindow = require('electron').remote.BrowserWindow
const ipcRenderer = require('electron').ipcRenderer
const path = require('path')

const invisMsgBtn = document.getElementById('invis-msg')
const invisReply = document.getElementById('invis-reply')

invisMsgBtn.addEventListener('click', function (clickEvent) {
  const windowID = BrowserWindow.getFocusedWindow().id
  const invisPath = 'file://' + path.join(__dirname, '../../sections/communication/invisible.html')
  let win = new BrowserWindow({ width: 400, height: 400, show: false })
  win.loadURL(invisPath)

  win.webContents.on('did-finish-load', function () {
    const input = 100
    win.webContents.send('compute-factorial', input, windowID)
  })
})

ipcRenderer.on('factorial-computed', function (event, input, output) {
  const message = `${input} 的阶乘是 ${output}`
  invisReply.textContent = message
})

隐藏窗口页面的HTML

 

Electron框架中,创建两个窗口并不需要通过主进程直接通信,如果你想要两个窗口间直接交流,特别是当它们都在同一进程中运行时,你可以利用Electron的一些特定机制,如: 1. **WebContents API**:每个窗口都有一个`webContents`对象,它代表了一个浏览器实例。你可以获取另一个窗口的`webContents`实例,并使用它的`send`和`receiveMessage`方法来进行跨窗口通信。例如: ```javascript const win = BrowserWindow.getAllWindows()[1]; // 获取第二个窗口实例 win.webContents.send('message-type', 'hello from window 1'); ``` 接收端可以在事件处理器中监听这个消息: ```javascript win.webContents.on('ipc-message-received', (event, arg) => { console.log(`Received message: ${arg} from window 2`); }); ``` 2. **Channel messaging**:在 Electron v10 及以上版本,推荐使用 `chrome.ipcRenderer` 和 `chrome ipcMain` 来实现跨窗口通信,这种方式更安全且支持跨进程。但是,这种方法仍然需要在主进程渲染进程中设置好相应的通道。 3. **共享内存或本地消息传递**:如果数据量不大且不需要频繁交互,还可以考虑使用共享内存(`preload.js`文件)或者使用Electron内置的`remote`模块来在主进程渲染进程中传递数据。 然而,要注意的是,出于安全性和性能的考量,不是所有情况都适合窗口之间直接通信,特别是在大型应用或多线程场景下。通常,主进程作为协调者,负责处理复杂的业务逻辑和跨窗口操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值