Electron 主進程給渲染進程發消息,渲染進程收不到的問題


正常接收的

先看個正常的代碼

主進程

//為了管理應用程序的生命周期事件以及創建和控制瀏覽器窗口,您從 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>

image-20210303093912975

可以看到能夠正常的接收

去掉延時發送

這時候你去掉延時發送,你會發現收不到了

更改后的主進程

//為了管理應用程序的生命周期事件以及創建和控制瀏覽器窗口,您從 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()
    }
})

啥也沒有

image-20210303094152507

這是為啥呢?

原因分析

我們看下官網寫法

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事件,那這個事件是干嘛的呢,官網也有說明

實例事件

Event: 'did-finish-load'

導航完成時觸發,即選項卡的旋轉器將停止旋轉,並指派onload事件后。

Event: 'did-fail-load'

返回:

  • event Event
  • errorCode Integer
  • errorDescription String
  • validatedURL String
  • isMainFrame Boolean
  • frameProcessId Integer
  • frameRoutingId 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()
    }
})

效果

image-20210303102502995


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM