`BrowserView`和`Electron中的`renderer` React页面之间的消息

olhwl3o2  于 2023-04-09  发布在  Electron
关注(0)|答案(1)|浏览(263)

我试图弄清楚如何在main进程和BrowserView之间交换消息。
我一直在“简单”react renderer page中的main进程和renderer进程之间使用ipc
但是现在,使用相同的技术,我在BrowserViewconsole中看不到收到的消息,据我所知,这似乎与“正常”react renderer page的行为不同。这篇SOF文章似乎证实了我的假设:Electron BrowserView Renderer process vs WebView
preload中,我定义:

declare global {
    interface Window {
        api: {
            electronIpcSend: (channel: string, ...arg: any) => void;
            electronIpcOn: (channel: string, listener: (event: any, ...arg: any) => void) => void;
        }
    }
}

main中,我有:

function createWindowTypeC (url_string: string) {
    WindowTypeC = new BrowserWindow({
    
        width: 800,
        height: 600,
        webPreferences: {
            nodeIntegration: false,
            contextIsolation: true,
            nodeIntegrationInWorker: false,
            sandbox: true,
            nodeIntegrationInSubFrames: false,
            webSecurity: true,
            webviewTag: false,
            preload: path.join(__dirname, "./preload/preload.js"), /* eng-disable PRELOAD_JS_CHECK */
        }
    })
    
    // and load the index.html of the app.
    
    // Emitted when the window is closed.
    WindowTypeC.on('closed', () => {
        WindowTypeC.removeBrowserView(view_C)
        WindowTypeC = null
    })
    
    enforceInheritance(WindowTypeC.webContents)
    
    // https://www.electronjs.org/docs/latest/api/browser-view
    
    let view_C = new BrowserView()
    
    
    view_C.webContents.once('did-finish-load', () => {
        contents.focus()

        view_C.webContents.send('ping', 'whoooooooooh!')
    })
    
    view_C.setAutoResize({
        width: true,
        height: true,
        horizontal: true,
        vertical: true
    })
    
    WindowTypeC.setBrowserView(view_C)
    view_C.setBounds({ x: 0, y: 0, width: 800, height: 600 })
    view_C.setBackgroundColor("#1e1e1e")
    
    setTimeout(() => {
        view_C.webContents.loadURL(url_string)
    }, 200)
    
    view_C.webContents.openDevTools({
        mode: 'left'
    })
}

App_C.tsx中,我有:

import * as React from 'react';
    
function App_C(props) {
    
    window.api.electronIpcOn('ping', (event, message) => {
        console.log("App_C-window.api.electronIpcOn-ping-message: ", message)
     })

     window.api.electronIpcSend('pong', "Hello from App_C.tsx")

     return (
         <div id="outer-container" className='outer-container'>
             <h1>App_C</h1> 
         </div>
     );
}
    
export default App_C;

执行代码后,页面被正确呈现,但我没有看到任何从BrowserView发送到renderer进程的消息。
第二,抵押品,问题,是:如何在发送消息的途中返回,在BrowserView发送的renderer进程?
第三个问题:如何与BrowserView渲染的页面交互?

mi7gmzs6

mi7gmzs61#

在Electron中,您可以使用相同的进程间通信(IPC)机制在主进程和BrowserView之间进行通信,就像在主进程和渲染器进程之间进行通信一样。
要从主进程向BrowserView发送消息,请使用webContents.sendToFrame()方法。要从主进程中的BrowserView接收消息,请使用ipcMain.on()方法。
要从BrowserView向主进程发送消息,请使用ipcRenderer.send()。要从BrowserView中的主进程接收消息,请使用ipcRenderer.on()方法。
要与BrowserView中呈现的页面交互,请使用BrowserView的webContents对象的webContents.executeJavaScript()方法。
要从主进程向BrowserView发送消息,请执行以下操作:

const view = new BrowserView()
win.setBrowserView(view)
view.setBounds({ x: 0, y: 0, width: 800, height: 600 })
view.setAutoResize({ width: true, height: true, horizontal: true, vertical: true })

view.webContents.on('did-finish-load', () => {
  const frameId = view.webContents.getFrameId('my-frame')
  view.webContents.sendToFrame(frameId, 'ping', 'Hello from main process')
})

要从主进程中的BrowserView接收消息,请执行以下操作:

// In the main process
const view = new BrowserView()
win.setBrowserView(view)

view.webContents.on('ipc-message', (event, channel, message) => {
  console.log(`Received message ${channel} from BrowserView: ${message}`)
})

ipcMain.on('pong', (event, message) => {
  console.log(`Received message pong from BrowserView: ${message}`)
})

要从BrowserView向主进程发送消息,请执行以下操作:

// In the BrowserView's renderer process
const { ipcRenderer } = require('electron')

ipcRenderer.send('pong', 'Hello from BrowserView')

// In the main process
ipcMain.on('pong', (event, message) => {
  console.log(`Received message pong from BrowserView: ${message}`)
})

要与BrowserView中呈现的页面交互,请执行以下操作:

const view = new BrowserView()
win.setBrowserView(view)

view.webContents.on('did-finish-load', () => {
  view.webContents.executeJavaScript(`
    document.querySelector('input[name="username"]').value = 'John Doe'
  `)
})

相关问题