Electron中的IPC通讯总结

news/2025/4/3 6:59:18/文章来源:https://www.cnblogs.com/niehao/p/18805274

单向通讯( 渲染进程 -> 主进程 )


// 主进程 main.jsipcMain.on('set-title', (event, title) => {})// 预加载脚本 preload.js
const { contextBridge, ipcRenderer } = require('electron/renderer')
contextBridge.exposeInMainWorld('electronAPI', {setTitle: (title) => ipcRenderer.send('set-title', title)
})// 实际调用,渲染进程
setButton.addEventListener('click', () => {const title = titleInput.valuewindow.electronAPI.setTitle(title)
})

单向通讯( 主进程 -> 渲染进程 )

将消息从主进程发送到渲染器进程时,需要指定是哪一个渲染器接收消息。消息需要通过WebContents实例发送到渲染器进程。此WebContents实例包含一个send方法,其使用方式与ipcRenderer.send相同。

对于从主进程到渲染器进程的 IPC,没有与 ipcRenderer.invoke 等效的 API。 不过,您可以从 ipcRenderer.on 回调中将回复发送回主进程(通过 单向通讯 渲染进程 -> 主进程)

// 主进程 main.js
function createWindow () {const mainWindow = new BrowserWindow({webPreferences: {preload: path.join(__dirname, 'preload.js')}})mainWindow.webContents.send('update-counter', 1)mainWindow.loadFile('index.html')
}// 预加载脚本 preload.js 
const { contextBridge, ipcRenderer } = require('electron/renderer')
contextBridge.exposeInMainWorld('electronAPI', {onUpdateCounter: (callback) => ipcRenderer.on('update-counter', (_event, value) => callback(value)),
})// 实际调用,渲染进程
const counter = document.getElementById('counter')
window.electronAPI.onUpdateCounter((value) => {const oldValue = Number(counter.innerText)const newValue = oldValue + valuecounter.innerText = newValue.toString()
})

双向通讯(渲染进程 <-> 主进程)

// 方法1:渲染进程请求,主进程方法,并等待其结果;(ipcRenderer.invoke 和 ipcMain.handle 配对使用)
// 示例:从渲染器进程打开一个原生的文件对话框,并返回所选文件的路径。// 主进程 main.js
async function handleFileOpen () {const { canceled, filePaths } = await dialog.showOpenDialog()if (!canceled) {return filePaths[0]}
}ipcMain.handle('dialog:openFile', handleFileOpen)// 预加载脚本 preload.js 
const { contextBridge, ipcRenderer } = require('electron/renderer')
contextBridge.exposeInMainWorld('electronAPI', {openFile: () => ipcRenderer.invoke('dialog:openFile')
})// 实际调用,渲染进程
const btn = document.getElementById('btn')
const filePathElement = document.getElementById('filePath')
btn.addEventListener('click', async () => {const filePath = await window.electronAPI.openFile()filePathElement.innerText = filePath
})
// 方法2:  单向通信的 ipcRenderer.send API 也可用于双向通信。 这是在 Electron 7 之前通过 IPC 进行异步双向通信的推荐方式。// 主进程 main.js
ipcMain.on('asynchronous-message', (event, arg) => {console.log(arg) // 在 Node 控制台中打印“ping”// 作用如同 `send`,但返回一个消息,到发送原始消息的渲染器event.reply('asynchronous-reply', 'pong')
})// 预加载脚本  preload.js
const { ipcRenderer } = require('electron')
ipcRenderer.on('asynchronous-reply', (_event, arg) => {console.log(arg) // 在 DevTools 控制台中打印“pong”
})
ipcRenderer.send('asynchronous-message', 'ping')
// 方法3: ipcRenderer.sendSync API 向主进程发送消息,并 同步 等待响应。// 主进程 main.js
const { ipcMain } = require('electron')
ipcMain.on('synchronous-message', (event, arg) => {console.log(arg) // 在 Node 控制台中打印“ping”event.returnValue = 'pong'
})// 预加载脚本 preload.js
const { ipcRenderer } = require('electron')
const result = ipcRenderer.sendSync('synchronous-message', 'ping')
console.log(result) // 在 DevTools 控制台中打印“pong”

双向通讯(渲染进程 <-> 渲染进程)

没有直接的方法可以使用 ipcMainipcRenderer 模块在 Electron 中的渲染器进程之间发送消息。 为此,您有两种选择:

  • 将主进程作为渲染器之间的消息代理。 这需要将消息从一个渲染器发送到主进程,然后主进程将消息转发到另一个渲染器。
  • 将MessagePort从主进程传递到两个渲染进程。 这将允许在初始设置后渲染器之间直接进行通信。
// 在两个渲染进程之间建立 MessageChannel
// 在这个示例中,主进程设置了一个MessageChannel,然后将每个端口发送给不同的渲染进程。 这样可以让渲染进程彼此之间发送消息,而无需使用主进程作为中转。// 主进程 main.js
const { BrowserWindow, app, MessageChannelMain } = require('electron')app.whenReady().then(async () => {// 创建窗口const mainWindow = new BrowserWindow({show: false,webPreferences: {contextIsolation: false,preload: 'preloadMain.js'}})const secondaryWindow = new BrowserWindow({show: false,webPreferences: {contextIsolation: false,preload: 'preloadSecondary.js'}})// 建立通道const { port1, port2 } = new MessageChannelMain()// webContents准备就绪后,使用postMessage向每个webContents发送一个端口。mainWindow.once('ready-to-show', () => {mainWindow.webContents.postMessage('port', null, [port1])})secondaryWindow.once('ready-to-show', () => {secondaryWindow.webContents.postMessage('port', null, [port2])})
})// 预加载脚本 preload.js
const { ipcRenderer } = require('electron')ipcRenderer.on('port', e => {// 接收到端口,使其全局可用。window.electronMessagePort = e.ports[0]window.electronMessagePort.onmessage = messageEvent => {// 处理消息}
})

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/909900.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux shell command lsof All In One

Linux shell command lsof All In One lsof - list open filesLinux shell command lsof All In Onelsof - list open filesdemos # $ cd ./Desktop && man lsof > man-lsof.md$ cat man-lsof.md$ lsof -i(🐞 反爬虫测试!打击盗版⚠️)如果你看到这个信息, 说明…

FastAPI中Pydantic异步分布式唯一性校验

title: FastAPI中Pydantic异步分布式唯一性校验 date: 2025/04/02 00:47:55 updated: 2025/04/02 00:47:55 author: cmdragon excerpt: FastAPI开发中,异步分布式唯一性校验通过异步IO、分布式锁和二级缓存技术解决传统同步校验的并发冲突、性能瓶颈和响应延迟问题。手机和邮…

团对展示--自我介绍

团队展示 队名:DeepSleep队员姓名 队员学号吴钊鑫(组长) 3123004244薛考瑶 3223004258苏雨童 3223004255林赛强 3123004184李锦 3123004270蔡梓欣 3223004209左栋立 3123004294队员风采 吴钊鑫风格:追求简洁高效的解决方案 擅长技术:C++ 编程兴趣:热衷于学习新兴技术 希望…

国家公路网规划 All In One

国家公路网规划 All In One 2022 年 7 月 国家公路网规划总规模约 46.1 万公里,由国家高速公路网和普通国道网组成,其中国家高速公路约16.2 万公里(含远景展望线约0.8 万公里),普通国道约 29.9 万公里。国家公路网规划 All In One2022 年 7 月国家公路网规划总规模约 46.1…

Learned Cardinalities: Estimating Correlated Joins with Deep Learning

这篇文章介绍了一个叫做MSCN的方法,这是一个应用于集合的深度学习网络,文章使用这个方法去做查询的基数估计。 文章将输入处理为集合的形式,具体大概是这个形状:像table set里每个元素(即一个向量)代表一个对应的表和在这个表中采样的位图,join set表示链接的集合,pred…

64位程序崩溃-访问越界

事件起因 最近在做一个32位程序编译成64位的工作,遇到一个很奇葩的问题,程序在32位下运行非常正常,可编译64位以后总是莫名崩溃,崩溃的的报错是这样的。 经过分析发现原来是以前的代码用DWORD来存储指针导致的地址越界错误。 现场模拟 先看一段代码 #include <stdio.h&g…

VMware 1067启动NATservice失败

VMware 1067启动NATservice失败可以检查下你的vmware虚拟网络编辑器看看是否nat模式还在,子网ip是否发生变化,Nat设置网关,改回原来就好 如果没有设置静态ip,直接还原默认设置就行

SLS 重磅升级:超大规模数据实现完全精确分析

SLS 全新推出的「SQL 完全精确」模式,通过“限”与“换”的策略切换,在快速分析与精确计算之间实现平衡,满足用户对于超大数据规模分析结果精确的刚性需求。标志着其在超大规模日志数据分析领域再次迈出了重要的一步。作者:执少 引言 在亿级日志分析中,你是否遇到过结果不…

C++多线程初步

1.多线程初步 1.包含的库 #Include<thread>2.涉及到的类 std::thread(这个类是属于标准模版库的,底层封装的系统调用) 3.代码实例 #include <iostream> #include <thread> void hello(){ std::cout << "Hello World" << std::en…

全定制电路Flow手册

简单做个summary手册,方便后面查阅以及组里统一规范。 全定制电路Flow手册 编写人:袁易扬 联系方式:2861704773@qq.com文档版本 编写日期 说明v1.0 2024.3.27 初次发布1. 工具链 原理图: Cadence Virtuoso IC617/618(用于22nm及以上的平面CMOS工艺) Cadence Virtuoso ICA…

Ajax、vue-cli、element

Ajax(Asynchronous JavaScript And XML)异步的JavaScript和XML 作用:数据交换:通过Ajax可以给服务器发送请求,并获取服务器响应的数据。 异步交互:可以在不重新加载整个页面的情况下,与服务器交换数据并更新部分网页的技术Axios:对原生Ajax进行封装,简化书写,快速开…

Hutool工具TreeUtil构建树形结构

1.导入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>cn.hutool</groupId><artifactId>hutool-core</a…