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

问题描述 投票:0回答:1

我正在尝试弄清楚如何在

main
进程和
BrowserView
之间交换消息。

我一直在“简单”

ipc
中的
main
过程和
renderer
过程之间使用
react renderer page

但是现在,使用相同的技术,我在

console
BrowserView
中看不到收到的消息,据我所知,它的行为似乎与“正常”
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
渲染的页面进行交互?

electron renderer
1个回答
0
投票

要从浏览器视图向主进程发送消息,您可以从浏览器视图使用console.log并在主进程中监视

console-message

view.webContents.on("console-message", (evt, logLevel, message, lineNumber, source) => {
  if (source.endsWith("/mybrowserview.js"))
    // do something with message
});

请注意,这将拾取所有控制台消息,因此您需要检查消息是否采用预期格式,如果不是则忽略它。例如,您的消息可以采用以下格式:

console.log('{"request":"myrequest","value":"myvalue"}');

然后您可以检查它是否是一个请求,例如:

view.webContents.on("console-message", (evt, logLevel, message, lineNumber, source) => {
  if (source.endsWith("/mybrowserview.js"))
      if (!isJsonString(message) || !message.includes('"request"'))
          return;

      // Looks like a valid request - do something with it
      let jsn = JSON.parse(message);

      if(jsn.request == "myrequest")
          ...
});


function isJsonString(str) {
  try {
    JSON.parse(str);
  } catch (e) {
    return false;
  }
  return true;
}

要从 main 向 browserview 发送消息,您可以执行一些 javascript,例如调用 browserview 中已有的函数:

view.webContents.executeJavaScript('myfunction("some message")');

在浏览器视图中你会看到类似的内容:

function myfunction(message) {
  // do something with message
  if (message == "whatever")
      ...
}
© www.soinside.com 2019 - 2024. All rights reserved.