Electron ipcMain 和 ipcRenderer 无法相互通信
Electron ipcMain & ipcRenderer fail to communicate with each other
我正在用 electron js 编写一个桌面应用程序,我想将数据从我的主进程发送到我的渲染器进程,反之亦然。为此,我使用 ipcMain
和 ipcRenderer
,但奇怪的是,虽然能够使用 ipcRenderer.send()
通过我的渲染器发送数据,但我无法使用 ipcRenderer.on()
。它只是出于某种原因不起作用。
之后我尝试通过编写测试来查找 bug,并遵循 electron 的文档。然而,该测试根本不起作用,因为这两个进程似乎都无法向另一个进程发送内容。这是我为测试编写的代码:
main.js:
const { app, ipcMain, BrowserWindow } = require('electron');
const createWin = async () => {
const win = new BrowserWindow({
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
},
});
win.loadFile('./index.html');
return new Promise((resolve, reject) => {
win.once('ready-to-show', () => {
resolve();
});
});
};
app.whenReady().then(async () => {
const win = await createWin();
console.log('Ready to show');
ipcMain.on('asynchronous-message', (event, arg) => {
console.log(arg); // prints "ping"
event.reply('asynchronous-reply', 'pong');
});
ipcMain.on('synchronous-message', (event, arg) => {
console.log(arg); // prints "ping"
event.returnValue = 'pong';
});
});
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Test, please work</title>
</head>
<body>
<script src="./app.js"></script>
</body>
</html>
app.js:
const { ipcRenderer } = require('electron');
console.log(ipcRenderer.sendSync('synchronous-message', 'ping')); // prints "pong"
ipcRenderer.on('asynchronous-reply', (event, arg) => {
console.log(arg); // prints "pong"
});
ipcRenderer.send('asynchronous-message', 'ping');
这是渲染器记录的内容:
{ error: "reply was never sent" }
这是文档的 link,我从中获得代码:https://www.electronjs.org/docs/api/ipc-main#sending-messages
发生这种情况是因为您连接事件处理程序的时间太晚了。
您只是在页面加载且 ready-to-show
已触发后才添加 ipcMain.on
。您应该更早地设置它们,就像在创建 window 之前一样,或者只是删除 await createWin()
.
中的 await
供参考,Electron 抛出错误 here
我正在用 electron js 编写一个桌面应用程序,我想将数据从我的主进程发送到我的渲染器进程,反之亦然。为此,我使用 ipcMain
和 ipcRenderer
,但奇怪的是,虽然能够使用 ipcRenderer.send()
通过我的渲染器发送数据,但我无法使用 ipcRenderer.on()
。它只是出于某种原因不起作用。
之后我尝试通过编写测试来查找 bug,并遵循 electron 的文档。然而,该测试根本不起作用,因为这两个进程似乎都无法向另一个进程发送内容。这是我为测试编写的代码:
main.js:
const { app, ipcMain, BrowserWindow } = require('electron');
const createWin = async () => {
const win = new BrowserWindow({
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
},
});
win.loadFile('./index.html');
return new Promise((resolve, reject) => {
win.once('ready-to-show', () => {
resolve();
});
});
};
app.whenReady().then(async () => {
const win = await createWin();
console.log('Ready to show');
ipcMain.on('asynchronous-message', (event, arg) => {
console.log(arg); // prints "ping"
event.reply('asynchronous-reply', 'pong');
});
ipcMain.on('synchronous-message', (event, arg) => {
console.log(arg); // prints "ping"
event.returnValue = 'pong';
});
});
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Test, please work</title>
</head>
<body>
<script src="./app.js"></script>
</body>
</html>
app.js:
const { ipcRenderer } = require('electron');
console.log(ipcRenderer.sendSync('synchronous-message', 'ping')); // prints "pong"
ipcRenderer.on('asynchronous-reply', (event, arg) => {
console.log(arg); // prints "pong"
});
ipcRenderer.send('asynchronous-message', 'ping');
这是渲染器记录的内容:
{ error: "reply was never sent" }
这是文档的 link,我从中获得代码:https://www.electronjs.org/docs/api/ipc-main#sending-messages
发生这种情况是因为您连接事件处理程序的时间太晚了。
您只是在页面加载且 ready-to-show
已触发后才添加 ipcMain.on
。您应该更早地设置它们,就像在创建 window 之前一样,或者只是删除 await createWin()
.
await
供参考,Electron 抛出错误 here