近半年做完了一个electron的项目,知识点记录如下: 项目搭建:eletron-vue 项目打包:eletron-builder 为什么使用eletron-builder,支持更多的平台(可以打包成msi、exe、dmg文件),同时也支持了自动更新,由electron-builder打出的包更为轻量,并且可以打包出不暴露源码的setup安装程序,另一种是eletron-packager 配置nsis自定义安装目录以及安装个性化 知识点: 一、electron 1、主进程和渲染进程 主进程就是 package.json 里的 main 脚本,在当前这个库里,主进程就是 main.js 这个文件,在主进程中运行的脚本通过创建 web 页面来展示用户的界面。 Electron 的内核是 Chromium ,所以 Chromium 的多进程架构也会被使用到,每个 Electron 中的 web 页面都会运行在自己的渲染进程中。
main.js 就是主进程,在主进程里通过 new BrowserWindow 创建页面,每个 BrowserWindow 就是渲染进程,当某个 BrowserWindow 页面被销毁后,对应的渲染进程也会被终止。
2、优化窗口
1、无边框窗口
mainWindow = new BrowserWindow({width: 800, height: 600, frame: false, resizable: false});
2、窗口拖动
现在窗口已经没有标题栏和菜单栏了,所以窗口没办法拖动了,给拖动区域增加 -webkit-app-region: drag 的 CSS 代码。
<body style="-webkit-app-region: drag"></body>
需要注意的是,如果在拖动区域里有按钮等需要点击的元素,需要增加 -webkit-app-region: no-drag 设置,否则会无法点击。
3、进程间通信
因为安全限制, web 页面不能直接访问原生 GUI 资源,在 Electron 中也是一样,渲染进程如果想要进行原生的 GUI 操作,就比如和主进程进行通信,请求相应的操作。在 Electron 中提供了几种通信方式
1、ipcMain 和 ipcRenderer
在渲染进程中使用 ipcRenderer 模块向主进程发送消息,主进程中使用 ipcMain 模块接收消息,进行操作,如果还需要反馈,则通知渲染进程,渲染进程根据接收的内容执行相应的操作:
// 渲染进程中
const {ipcRenderer} = require('electron');
ipcRender.send('somemsg', data);
ipcRender.on('replaymsg', (evt, otherData) => {
console.log(otherData);
});
// 主进程中
const {ipcMain} = require('electron');
ipcMain.on('somemsg', (evt, data) => {
console.log(data);
evt.sender.send('replymsg', otherData);
});
2、remote
remote 模块为渲染进程和主进程通信提供了一种简单方法,可以看到在上面手动实现拖动窗口的效果里,就用到了 remote 模块。
3、webContents
// 主进程中
win.webContents.on('did-finish-load', () => {
win.webContents.send('ping', 'whoooooooh!');
});
// 渲染进程中
require('electron').ipcRenderer.on('ping', (event, message) => {
console.log(message);
});
4、渲染进程之间通信
h5:使用Vuex,router
但如果对数据实时性要求高,那就要结合上面的方法来实现:
// 主进程中,将两个窗口的 id 分别发送到对方的渲染进程里
mainWindow.webContents.on('did-finish-load', () => {
mainWindow.webContents.send('getChild', {
childId: childWindow.id
});
});
childWindow.webContents.on('did-finish-load', () => {
childWindow.webContents.send('getMain', {
mainId: mainWindow.id
});
});
// 渲染进程 mainWindow,通过 id 得到 childWindow 并发送一条消息
ipcRenderer.on('getChild', (event, arg) => {
remote.BrowserWindow.fromId(arg.childId).webContents.send('say', 'Hello World!');
});
// 渲染进程 childWindow,接收 mainWindow 的消息
ipcRenderer.on('say', (event, arg) => {
console.log(arg); // 输出:Hello World!
});
// 同理 childWindow 也可以通过 id 给 mainWindow 发送消息
二、直播流
rtmp 只支持pc,需要sdk,延迟较小,比较稳定,需要flash或者ckplayer(也需要flashplayer)播放
hls 支持h5不需要sdk,pcweb需要sdk,有些手机浏览器autoplay有兼容性,在PC上播放延迟10s+
需要播放rtmp,.swf必须是远程的,本地的会无法加载,文件也必须放到服务器才可以播放
踩坑: electron里使用elementUI等,需要在webpack.renderer.config.js的白名单里配置:let whiteListedModules = ['vue', 'element-ui'] 在windows7的盗版系统上,无法安装应用,报错APPCRASH c0000374,无法联机,其他正常的windows7播放正常
疑问: 在electron里接入直播,使用rtmp标准流播放直播,打包后无法播放,显示播放无法加载,最始的想法是接入pepflashplayer插入,并开启插件webPreferences: {plugins: true},在开发环境是可以正常播放的,打包后的navigator.plugins有显示flash插件,electron官方是有介绍需要授权.swf文件,但ckplayer里的swf不支持本地播放rtmp,不明所以,先记录
难点: 1、多窗口的管理,每个窗口使用remote.getCurrentWindow().id命名,在主进程中采用单个实例app.makeSingleInstance管理 2、接入直播,目前使用c#语言编写直播功能,接入直播的exe,并传递参数通信等