现在使用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通信一样,只不过有这两个就够了,如果想,可以进一步讨论