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));
相关推荐
崔庆才丨静觅4 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60615 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了5 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅5 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅6 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅6 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment6 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅6 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊6 小时前
jwt介绍
前端
爱敲代码的小鱼7 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax