答案 0 :(得分:7)
要记住的主要事情是,在Electron中,interProcess通信由ipcMain(在主进程中)和ipcRenderer(在所有创建的窗口中)完成。如下所示: 根据我在GitHub评论中看到的内容 - 不允许在Renderer实例之间进行直接通信。一切都必须通过mainProcess。
代码: 的 mainProcess.js:强>
function createWindow1 () {
window1 = new BrowserWindow({width: 800,height: 600})
window1.loadURL(`file://${__dirname}/window1.html`)
window1.webContents.openDevTools()
window1.on('closed', function () {
window1 = null
})
return window1
}
function createWindow2 () {
window2 = new BrowserWindow({width: 1000, height: 600})
window2.loadURL(`file://${__dirname}/window2.html`)
window2.webContents.openDevTools()
window2.on('closed', function () {
window2 = null
})
return window2
}
app.on('ready', () => {
window1 = createWindow1();
window2 = createWindow2();
ipcMain.on('nameMsg', (event, arg) => {
console.log("name inside main process is: ", arg); // this comes form within window 1 -> and into the mainProcess
event.sender.send('nameReply', { not_right: false }) // sends back/replies to window 1 - "event" is a reference to this chanel.
window2.webContents.send( 'forWin2', arg ); // sends the stuff from Window1 to Window2.
});
<强> window1.html:强>
<body>
<input type="text" id="name" value="" placeholder="Enter your name">
<button type="button" id="sendName" >Send the name! </button>
</body>
<script>
// You can also require other files to run in this process
require('./window1.js')
</script>
<强> window1.js:强>
const ipcRenderer = require('electron').ipcRenderer
let name = document.getElementById('name');
ButtonSendName = document.getElementById('sendName');
ButtonSendName.addEventListener('click', (event) => {
ipcRenderer.send('nameMsg', name.value);
})
ipcRenderer.on('nameReply', (event, arg) => {
console.log(arg) // why/what is not right..
});
window2.html:
<body>
<p id = "showName"></p>
</body>
<script>
require('./window2.js')
</script>
<强> window2.js:强>
const { ipcRenderer } = require('electron')
showName = document.getElementById('showName')
ipcRenderer.on('forWin2', function (event, arg){
console.log(arg);
showName.innerHTML = arg;
});
console.log("I'm Window2");
演示会更好,但我不知道如何构建电子CodeBin应用程序。这张图片给你一个想法:
享受Electron的力量!
答案 1 :(得分:0)
根据您的要求,可以创建SharedWorker,它充当在Windows之间传输MessagePort的代理。注意:SharedWorker要求所有窗口都从同一来源运行(可能不符合您的要求)。因此,例如,在主窗口中创建一个MessageChannel(具有两个端口),然后将端口1通过SharedWorker传输到一个窗口,将端口2传输到另一个窗口。现在,两个窗口可以使用postMessage通过端口直接通信。作为奖励,postMessage还支持可转换。我当时正在研究这个想法,但尚未完全开发该库,但是您可以从此处进行的一些工作中获得这个想法:https://github.com/lneir/electron-direct-comm
答案 2 :(得分:0)
每当我们谈到在Electron应用程序中从一个窗口到另一个窗口进行通信时,您总是想着IPC系统,即进程间通信。
因此,在一个窗口中,您将监听一个事件,例如表单提交。
提交表单后,您可以从输入中删除文本并将事件发送到Electron应用程序。
然后,Electron应用将触发其自己的事件,并将事件继续发送到mainWindow
,后者将接收文本并将其附加到其列表中。
您可以在辅助window.html文件中仅使用原始JavaScript来开始,如下所示:
document.querySelector('form').addEventListener('submit', event => {
event.preventDefault();
});
因此,以上假设您正在使用要提交的表单。
答案 3 :(得分:0)
编辑:我为此创建了一个存储库:electron-multi-monitor:
我们的项目遇到了类似的问题。然而,两个 BrowserWindows 都必须来回传递 JS 对象和函数。
通过 IPC 调用提出的解决方案是我们尝试的第一件事,但还不够。当您只需要传递几个小对象但很快就会达到它的限制时,它非常有效,因为 Electron 将序列化通过 IPC 调用传递的所有数据。
我们前进的方式是使用 window.opener 功能。我们使用电子生成一个 main
BrowserWindow,然后通过 window.open() 打开所需数量的 side
浏览器窗口。 Electron 可以在这些窗口生成时定位它们。
接下来,每个 side
窗口将其 HTML DOM 注册为 main
窗口的 JS 窗口实例。这样,main
窗口就引用了 side
窗口的 DOM 和 JS 窗口实例。
从这里开始,main
窗口可以完全控制所有可用的窗口,并且可以在所有窗口上呈现新的 HTML、传递 JS 对象、调用 JS 函数……。我们个人使用 React Portals 来处理不同窗口上的渲染。
目前我不能分享一个完整的例子,但如果我有时间我会创建一个 github 存储库。
一些已经可以帮助您前进的事情:
affinity
(参见 BrowserWindow docs)nativeWindowOpen
项网络首选项仅供参考:您也可以直接在浏览器中使用此技术,但它们仍然不允许您在窗口中移动