3

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

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

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

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

在浏览器中查看 main processrenderer 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

<html>
  <script type="text/javascript">
    const ipc = require('electron').ipcRenderer
    const BrowserWindow = require('electron').remote.BrowserWindow

    ipc.on('compute-factorial', function (event, number, fromWindowId) {
      const result = factorial(number)
      const fromWindow = BrowserWindow.fromId(fromWindowId)
      fromWindow.webContents.send('factorial-computed', number, result)
      window.close()
    })

    function factorial (num) {
      if (num === 0) return 1
      return num * factorial(num - 1)
    }
  </script>
</html>

如果这边文章对您有帮助, 感谢 下方点赞 或 Star GitHub: electron-api-demos-Zh_CN 支持, 谢谢.


DemoPark
1.1k 声望177 粉丝

Just Full Stack Developer