Electron双向通讯的两种方法

800 阅读1分钟

双向通信

  • 方式一:就是把上一篇的两种方式进行结合。
  • 例子:点击按钮,向主进程发起进攻,主进程接收到信息之后,给予反馈。

index.html文件

<body>
   <button id='btn'>双向通讯</button>
</body>
<script src='renderer.js'></script>

渲染进程 renderer.js文件

window.addEventListener('DOMContentLoaded', () => {
   const el = doucment.getElementById( 'btn' );
   el.addEventlistener( 'click', () => {
      // 触发预加载文件暴露出来的事件
      window.api.jingong( );
   })
})

预加载文件 preload.js


 const { ContentBridge, ipcRenderer } = require( 'electron' );
 
 // 暴露事件,与渲染进程共享方法
 ContentBridge.exposeInMainWorld( 'api', {
   jingong: () => {
      ipcRenderer.send( 'saveFile' );
   }
 })
 
 // 监听主进程给予的反馈
 ipcRenderer.on( 'message', (event, arg) => {
   console.log( arg ); //已经收到保存文件指令!!!
 } )

主进程文件 main.js

    const { BrowerWindow, app} = require( 'electron' );

    function createWindow(){
       const mainWindow = new BrowserWindow({
          window: 500,
          height: 500,
          webPreferences:{
          preload: path.resolve(__dirname, 'preload.js'),
          }
       });
       
       mainWindow.loadFile( path.resolve(__dirname, 'index.html') )
    }
    
    // 初始化窗口
    app.whenReady().then(() => {
       createWindow();
    })
    
    // 监听ipcRenderer发出的saveFile事件
    ipcMain.on('saveFile', (event) => {
       // 给予反馈
       BrowserWindow.fromWebContents( event.sender ).send('message', '已经收到保存文件指令!!!')
    })
  • 方式二:预加载脚本中使用ipcRender.invoke('事件')向主进程发起任务通知,主进程通过ipcMain.handle()监听,进行逻辑处理

index.html文件

 <body>
       <button id='btn'>上传文件</button>
 </body>
 <script src='renderer.js'></script>
 

渲染进程 renderer.js

        window.addEventlistener('DOMContentLoaded', ()=>{
           const btn = document.getElementById( 'btn');
           btn.addEventlistener('click', () => {
           
              // 触发预加载脚本中暴露出来的upload方法,并传递callback
               window.api.upload( (imgUrl) =>{
                  const img = document.createElement( 'img' );
                  imr.src = imgUrl;
               } )
           })
        })

预加载脚本 preload.js

    const { ContentBridge, } = require('electron');

    ContentBridge.exposeInMainWorld('api', {
    
    // 向渲染进程暴露upload事件
      upload: async (callback) => {
         
         // 向主进程发出消息
         const imgUrl = ipcRenderer.invoke('uploadImg'); //它的结果是主进程的返回值
         callback(imgUrl);
      }
    })

主进程 main.js

const { dialog, ipcMain } = require('electron'); 

  // 主进程监听uploadImg事件
  ipcMain.handle('uploadImg', async () => { //这个事件return出去的会被对应的ipcRenderer.invoke接收到
    const obj =  dialog.showOpenFile();
    return obj.filePaths[0]; //这里返回的是图片地址
  })