Electron -- 进程消息通知

本文介绍了使用electron开发时候和消息传递相关的知识,包括主进程和渲染进程之间的通信,以及Web页面和主进程之间的通信。

1. ipcMain.on监听的是什么消息

ipcMain.on用于在Electron主进程(ipcMain)中监听从渲染进程(ipcRenderer)发送的消息。它是一个事件监听器,可以注册特定的事件名称,并在收到对应事件时触发回调函数;例如:

js 复制代码
const { ipcMain } = require('electron');

// 监听来自渲染进程的消息
ipcMain.on('message', (event, arg) => {
  console.log(arg); // 打印接收到的消息
});

2. 如何在ipcRenderer(渲染进程)中向ipcMain发送消息

在渲染进程

js 复制代码
const { ipcRenderer } = require('electron');

// 发送消息给主进程
ipcRenderer.send('message', 'Hello from renderer process!');

// 监听来自主进程的回复消息
ipcRenderer.on('reply', (event, arg) => {
  console.log(arg); // 打印收到的回复消息
});

3. 如何在ipcMain中向ipcRenderer发送消息

3.1 在ipcMain中通过win.webContents对象向此win对象对应的ipcRender发送消息,例如

js 复制代码
const { ipcMain, BrowserWindow } = require('electron');

// 创建窗口对象
let win = new BrowserWindow();

// 监听来自渲染进程的消息
ipcMain.on('messageToMain', (event, arg) => {
  console.log(arg); // 打印接收到的消息

  // 向特定窗口的渲染进程发送消息
  win.webContents.send('messageFromMain', 'Hello from main process!');
});

3.2 ipcMain收到消息之后回复发送消息的ipcRenderer

利用消息传递过程中,回调函数第一个参数,即事件对象event上的reply对象属性进行消息传递(准确来说是消息传递),例如:

js 复制代码
// 监听来自渲染进程的消息
ipcMain.on('message', (event, arg) => {
  console.log(arg); // 打印接收到的消息
  // 发送回复消息给渲染进程
  event.reply('reply', 'Hello from main process!');
});

4. ipcRender上与消息通知相关的方法

下面是七个使用ipcRenderer进行消息通知的示例,包括ipcMain和ipcRenderer两侧的代码:

4.1. ipcRenderer.send(channel, ...args): 主进程(ipcMain)代码:

javascript 复制代码
const { ipcMain } = require('electron');

ipcMain.on('messageToMain', (event, arg) => {
  console.log(arg); // 打印接收到的消息
});

// 渲染进程发送消息到主进程
ipcRenderer.send('messageToMain', 'Hello from renderer process!');

渲染进程(ipcRenderer)代码:

javascript 复制代码
const { ipcRenderer } = require('electron');

// 向主进程发送异步消息
ipcRenderer.send('messageToMain', 'Hello from renderer process!');

4.2. ipcRenderer.sendSync(channel, ...args): 区别在于ipcRenderer.sendSync是有返回值的,而ipcRenderer.send没有;这个区别很好的体现出了同步通信和异步通信的区别。

主进程(ipcMain)代码:

javascript 复制代码
const { ipcMain } = require('electron');

ipcMain.on('messageToMainSync', (event, arg) => {
  console.log(arg); // 打印接收到的消息

  // 向渲染进程返回同步消息
  event.returnValue = 'Hello back from main process!';
});

// 渲染进程发送同步消息到主进程
const result = ipcRenderer.sendSync('messageToMainSync', 'Hello from renderer process!');
console.log(result); // 打印接收到的返回结果

渲染进程(ipcRenderer)代码:

javascript 复制代码
const { ipcRenderer } = require('electron');

// 向主进程发送同步消息
const result = ipcRenderer.sendSync('messageToMainSync', 'Hello from renderer process!');
console.log(result); // 打印接收到的返回结果

4.3. ipcRenderer.invoke(channel, ...args)

  • 需要注意的是ipcRenderer.invoke和icpMain.handle搭配使用,和上面的ipcRenderer.send搭配ipcMain.on是不同的。
  • icpMain.handle的返回值是一个Promise对象,此对象包裹的数据正是ipcRenderer.invoke.then的接受数据。

主进程(ipcMain)代码:

javascript 复制代码
const { ipcMain } = require('electron');

ipcMain.handle('messageInvoke', async (event, arg) => {
  console.log(arg); // 打印接收到的消息

  // 模拟处理过程,返回Promise结果
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve('Hello back from main process!');
    }, 1000);
  });
});

// 渲染进程发送异步消息到主进程,并等待返回结果
ipcRenderer.invoke('messageInvoke', 'Hello from renderer process!')
  .then((result) => {
    console.log(result); // 打印接收到的返回结果
  });

渲染进程(ipcRenderer)代码:

javascript 复制代码
const { ipcRenderer } = require('electron');

// 向主进程发送异步消息,并等待返回结果
ipcRenderer.invoke('messageInvoke', 'Hello from renderer process!')
  .then((result) => {
    console.log(result); // 打印接收到的返回结果
  });

4.4. ipcRenderer.on(channel, listener): 正如前文所说:ipcRenderer.on和ipcRenderer.send或者win.webContents.send搭配使用。 主进程(ipcMain)代码:

javascript 复制代码
const { ipcMain } = require('electron');

ipcMain.on('messageToMain', (event, arg) => {
  console.log(arg); // 打印接收到的消息

  // 向渲染进程发送回复消息
  event.reply('messageFromMain', 'Hello back from main process!');
});

渲染进程(ipcRenderer)代码:

javascript 复制代码
const { ipcRenderer } = require('electron');

// 监听来自主进程的消息
ipcRenderer.on('messageFromMain', (event, arg) => {
  console.log(arg); // 打印接收到的消息
});

// 向主进程发送消息
ipcRenderer.send('messageToMain', 'Hello from renderer process!');

4.5. ipcRenderer.once(channel, listener): 主进程和渲染进程示例与示例4。4中的代码相同。唯一不同之处是使用ipcRenderer.once替代ipcRenderer.on,以确保监听器仅触发一次。

4.6. ipcRenderer.removeListener(channel, listener): 主进程和渲染进程示例与示例4中的代码相同。在需要移除特定监听器时,使用ipcRenderer.removeListener方法。

4.7. ipcRenderer.removeAllListeners([channel]): 移除所有或指定channel的监听器。

5. Web页面和主进程之间的通信

Web页面和主进程之间的通信的本质是ipcRenderer和ipcMain之间进行通信,本质上就是4中的7种方法;不同之处在于:

  • 在Electron中,为了确保Web页面与主进程之间的通信安全,需要使用contextBridge模块来限制对Electron API的访问。contextBridge提供了exposeInMainWorld方法,用于在渲染进程中暴露特定的API给主进程,以便进行双向通信。
  • 通过exposeInMainWorld,可以将自定义的API对象或函数注入到渲染进程的全局作用域中,使其可以直接在页面中访问,并与主进程进行通信。
javascript 复制代码
const { contextBridge, ipcRenderer } = require('electron');

// 
contextBridge.exposeInMainWorld('electronAPI', {

    // web页面获取渲染进程中的相关信息
    isPrimaryScreen: () => true,

    // web页面操作主进程方法
    exitApp: () => void ipcRenderer.send('closeMainWindow'),

    // web页面向主进程传递数据
    updateFocusWindow: index => void ipcRenderer.send('update-focus-window', index),

    // web页面将消息的回调函数注册到ipcRender中
    handleClearLocalStorage: callback => void ipcRenderer.on('clear-localStorage', callback),

    // web页面向主进程获取进程数据
    getLocalIP: () => ipcRenderer.invoke('get-local-ip'),

});

使用:

js 复制代码
console.log(window?.electronAPI.getLocalIP().then(data => data));
相关推荐
张晓~1833994812117 分钟前
数字人源码部署流程分享--- PC+小程序融合方案
javascript·小程序·矩阵·aigc·文心一言·html5
爱喝水的小周20 分钟前
AJAX vs axios vs fetch
前端·javascript·ajax
Jinxiansen021122 分钟前
unplugin-vue-components 最佳实践手册
前端·javascript·vue.js
几道之旅26 分钟前
介绍electron
前端·javascript·electron
周胡杰28 分钟前
鸿蒙arkts使用关系型数据库,使用DB Browser for SQLite连接和查看数据库数据?使用TaskPool进行频繁数据库操作
前端·数据库·华为·harmonyos·鸿蒙·鸿蒙系统
315356691329 分钟前
ClipReader:一个剪贴板英语单词阅读器
前端·后端
玲小珑31 分钟前
Next.js 教程系列(十一)数据缓存策略与 Next.js 运行时
前端·next.js
qiyue771 小时前
AI编程专栏(三)- 实战无手写代码,Monorepo结构框架开发
前端·ai编程
轻语呢喃1 小时前
React智能前端:从零开始的识图学单词项目(一)
javascript·react.js·aigc
断竿散人1 小时前
JavaScript 异常捕获完全指南(下):前端框架与生产监控实战
前端·javascript·前端框架