electron中原生与webview加载的h5通信方式实战

2,480 阅读2分钟

现在使用electron开发桌面端的技术已经很成熟了,最好的例子就是我们的开发工具vscode,轻量写插件方便。现在网上新出现的rust的tauri,看来各种文章的夸夸奇谈。rust我也用过(当初为了webassembly),没必要贬低electron,任何语言都是开发手段,用electron的目的是如果你是写前端的,或者写nodejs的,这时有个项目是桌面端,你选择electron过度很轻松。非要说tauri好,我为啥不用flutter(这个也用过,还没正式发布就用来写app了)。废话不多说,今天说的是electron实现原生与webview加载的h5通信,这个是用electron很常见的问题。

第一,使用electron自带的通信ipcRenderer与ipcMain

之前看到有人说webview中不能使用electron原生的api,其实可以,需要注入,就像以前写原生app(安卓,ios)加载h5时,就需要用到桥接,虽然安卓和IOS有自己的方便,但是这样就不统一需要写两套,用桥接的目的就是统一,这方法就是初始化webview时注入桥接文件,electron也是。 先设置这些

    webPreferences: {
      webviewTag: true,
      nodeIntegration: true,
      }

然后初始化webview时注入

 webview.setAttribute("preload", this.preloadPath)

preload.js文件是

const { ipcRenderer } = require("electron")
window._spenv = "electron"
ipcRenderer.on("native-event", (e, mgs) => {
  window.nativeEvent = { event: e, data: mgs }
})
window.electronEvent = {
  send: (event, message) => {
    ipcRenderer.sendToHost(event, message)
  }
}

这样你就可以在webview组件加载之后接受h5端的消息了

    webview.addEventListener("ipc-message", ({ channel, args }) => {
      this.$emit("change", channel, args)
    })

h5那边也就是监听window.nativeEvent就行了,到此,双方通信就完成了,有的人说不行是要么没配置好,要么就是少文件。

第二,使用websocket

websocket的话就没那么麻烦了,使用过的都知道,理解起来也简单,node端作为服务端,h5作为客户端,网上插件也不是,我使用的是WS。

  const wss = new WebSocketServer({ port: 8888 })
  if (worker) {
    wss.on('connection', function connection(ws) {
      console.log('connection')
      ws.on('message', function message(data) {
        worker.postMessage(JSON.parse(data.toString()))
      })
    })

客户端的话就更简单了,使用WebSocket,这是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。,浏览器自带的,但是要看下哪些支持,不过你用electron不用担心这个

      const busEvent = new WebSocket("ws://localhost:8888/")
      busEvent.onmessage = function(event) {
      }

至此WebSocket通信也完成了。

其实还有其他方式的通信,类似与app的webview通信一样,只不过有这两个就够了,如果想,可以进一步讨论