正常接收的
先看個正常的代碼
主進程
//為了管理應用程序的生命周期事件以及創建和控制瀏覽器窗口,您從 electron 包導入了 app 和 BrowserWindow 模塊 。
const { app, BrowserWindow,ipcMain } = require('electron')
//在此之后,你定義了一個創建 新的瀏覽窗口的函數並將 nodeIntegration 設置為 true,將 index.html 文件加載到窗口中(第 12 行,稍后我們將討論該文件)
function createWindow () {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
//是否注入nodeapi
nodeIntegration: true,
//渲染進程是否啟用remote模塊
enableRemoteModule: true
}
})
win.loadFile('index.html')
//2s后 , 主動發送
setTimeout(()=>{
win.webContents.send('send-message-to-render-test', '這是主進程的主動搭訕')
}, 2000)
}
//你通過調用 createWindow方法,在 electron app 第一次被初始化時創建了一個新的窗口。
app.whenReady().then(createWindow)
//您添加了一個新的偵聽器,當應用程序不再有任何打開窗口時試圖退出。 由於操作系統的 窗口管理行為 ,此監聽器在 macOS 上是禁止操作的
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
//您添加一個新的偵聽器,只有當應用程序激活后沒有可見窗口時,才能創建新的瀏覽器窗口。 例如,在首次啟動應用程序后或重啟運行中的應用程序
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})
渲染進程
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>進程通信</title>
</head>
<body>
<h1>進程通信</h1>
<button onclick="sendMessageMain()">發送信息給主進程</button>
</body>
<script>
const { ipcRenderer } = require('electron');
//監聽
ipcRenderer.on('send-message-to-render-test', (event, arg) => {
console.log('渲染進程收到的消息:',arg)
})
</script>
</html>
可以看到能夠正常的接收
去掉延時發送
這時候你去掉延時發送,你會發現收不到了
更改后的主進程
//為了管理應用程序的生命周期事件以及創建和控制瀏覽器窗口,您從 electron 包導入了 app 和 BrowserWindow 模塊 。
const { app, BrowserWindow,ipcMain } = require('electron')
//在此之后,你定義了一個創建 新的瀏覽窗口的函數並將 nodeIntegration 設置為 true,將 index.html 文件加載到窗口中(第 12 行,稍后我們將討論該文件)
function createWindow () {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
//是否注入nodeapi
nodeIntegration: true,
//渲染進程是否啟用remote模塊
enableRemoteModule: true
}
})
win.loadFile('index.html')
win.webContents.send('send-message-to-render-test', '這是主進程的主動搭訕')
}
//你通過調用 createWindow方法,在 electron app 第一次被初始化時創建了一個新的窗口。
app.whenReady().then(createWindow)
//您添加了一個新的偵聽器,當應用程序不再有任何打開窗口時試圖退出。 由於操作系統的 窗口管理行為 ,此監聽器在 macOS 上是禁止操作的
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
//您添加一個新的偵聽器,只有當應用程序激活后沒有可見窗口時,才能創建新的瀏覽器窗口。 例如,在首次啟動應用程序后或重啟運行中的應用程序
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})
啥也沒有
這是為啥呢?
原因分析
我們看下官網寫法
https://www.electronjs.org/docs/api/web-contents#contentssendchannel-args
// 在主進程中. const { app, BrowserWindow } = require('electron') let win = null app.whenReady().then(() => { win = new BrowserWindow({ width: 800, height: 600 }) win.loadURL(`file://${__dirname}/index.html`) win.webContents.on('did-finish-load', () => { win.webContents.send('ping', 'whoooooooh!') }) })
從上面看是監聽一個did-finish-load
事件,那這個事件是干嘛的呢,官網也有說明
導航完成時觸發,即選項卡的旋轉器將停止旋轉,並指派
onload
事件后。返回:
event
EventerrorCode
IntegererrorDescription
StringvalidatedURL
StringisMainFrame
BooleanframeProcessId
IntegerframeRoutingId
Integer
簡單理解就是渲染進程的頁面加載完了之后再觸發,到這里就明白了 ,主進程主動給渲染進程發送消息必須在渲染進程頁面渲染完成之后才可以。
解決辦法
主進程加上監聽 如
win.webContents.on('did-finish-load', () => {
win.webContents.send('ping', 'whoooooooh!')
})
將最開始的延時改成監聽
//為了管理應用程序的生命周期事件以及創建和控制瀏覽器窗口,您從 electron 包導入了 app 和 BrowserWindow 模塊 。
const { app, BrowserWindow,ipcMain } = require('electron')
//在此之后,你定義了一個創建 新的瀏覽窗口的函數並將 nodeIntegration 設置為 true,將 index.html 文件加載到窗口中(第 12 行,稍后我們將討論該文件)
function createWindow () {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
//是否注入nodeapi
nodeIntegration: true,
//渲染進程是否啟用remote模塊
enableRemoteModule: true
}
})
win.loadFile('index.html')
win.webContents.on('did-finish-load',() => {
win.webContents.send('send-message-to-render-test', '這是主進程的主動搭訕')
})
}
//你通過調用 createWindow方法,在 electron app 第一次被初始化時創建了一個新的窗口。
app.whenReady().then(createWindow)
//您添加了一個新的偵聽器,當應用程序不再有任何打開窗口時試圖退出。 由於操作系統的 窗口管理行為 ,此監聽器在 macOS 上是禁止操作的
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
//您添加一個新的偵聽器,只有當應用程序激活后沒有可見窗口時,才能創建新的瀏覽器窗口。 例如,在首次啟動應用程序后或重啟運行中的應用程序
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})
效果