我从Electron的主进程创建了多个窗口,需要在它们之间传递消息.我从rendererA向rendererB发送消息的唯一方法是将其弹回主进程.有没有办法直接从rendererA发送消息到renderB?
viv*_*ice 10
基本上,在电子中,进程之间的通信有三种形式:
webContents.fromId(id).send()在发送方,ipcRenderer.on在接收方ipcRenderer.send()在发送方,ipcMain.on在接收方ipcRenderer.sendTo()在发送方,ipcRenderer.on在接收方所以在渲染器到渲染器的场景中,发送者必须知道目的地的 webContents.id,然后通过 ipcRenderer.sendTo()
我制作了一个电子 ipc 框架,电子 ipcfy,它统一了上述所有三个场景中的 ipc 调用。
import { ipcfy } from "electron-ipcfy";
interface TestService {
greet(name: string);
}
const testService = ipcfy<TestService>('test');
if (process.type == 'browser') {
// Attach implementation
testService.__attachImpl(
new class implements TestService {
greet(name: string) {
console.log(`Hello, ${name}!`);
}
});
}
// Then you can call it in any process
testService.greet('world');
Run Code Online (Sandbox Code Playgroud)
小智 8
在某种程度上,主要过程必须参与,但两个窗口的渲染器过程之间的通信可以通过某种直接的方式实现:
在主进程中,将窗口引用定义为全局对象的属性;
在每个渲染器进程中,使用remote.getGlobal()访问要发送消息的窗口的引用,然后使用send()方法;
使用ipcRenderer.on()通常的方式在每个渲染器进程中接收消息.
main.js:
const { app, BrowserWindow } = require ('electron');
global.window1 = null;
global.window2 = null;
function onAppReady ()
{
window1 = new BrowserWindow ({ width: 600, height: 500 });
window1.loadURL (`file://${__dirname}/index1.html`);
window1.webContents.openDevTools ();
window1.on ('closed', () => { window1 = null; });
//
window2 = new BrowserWindow ({ width: 500, height: 600 });
window2.loadURL (`file://${__dirname}/index2.html`);
window2.webContents.openDevTools ();
window2.on ('closed', () => { window2 = null; });
}
app.on ('ready', onAppReady);
app.on ('window-all-closed', () => { app.quit (); });
Run Code Online (Sandbox Code Playgroud)
index1.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Window 1</title>
</head>
<body>
<h1>Window 1</h1>
<button type="button" class="send-message">Send Message to Window 2</button>
<script>
const { remote, ipcRenderer } = require ('electron');
//
let button = document.querySelector ('.send-message');
button.addEventListener ('click', () =>
{
let window2 = remote.getGlobal ('window2');
if (window2) window2.webContents.send ('message', "Message from Window 1");
});
//
ipcRenderer.on ('message', (event, message) => { console.log (message); });
</script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
index2.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Window 2</title>
</head>
<body>
<h1>Window 2</h1>
<button type="button" class="send-message">Send Message to Window 1</button>
<script>
const { remote, ipcRenderer } = require ('electron');
//
let button = document.querySelector ('.send-message');
button.addEventListener ('click', () =>
{
let window1 = remote.getGlobal ('window1');
if (window1) window1.webContents.send ('message', "Message from Window 2");
});
//
ipcRenderer.on ('message', (event, message) => { console.log (message); });
</script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
这取决于您的通信系统的逻辑。
例如,如果你总是需要从BrowserWindow2发送数据到BrowserWindow4,你可以在BrowserWindow4中声明ipcMain ,在BrowserWindow2中声明ipcRenderer 。
如果您必须从所有 BrowserWindows 发送到所有其他浏览器,我建议您使用 Main process 并将消息发送到 BrowserWindows (使用亲戚ID)
在您的消息接收器中:
ipcMain.on('asynchronous-message', (event, arg) => {
//manage data
}
Run Code Online (Sandbox Code Playgroud)
在您的消息发送者中:
ipcRenderer.send('asynchronous-message', message)
Run Code Online (Sandbox Code Playgroud)