前端开发利用Electron + node-serialpost实现串口通信,最近有需求尽可能直接读取地磅数据,现有项目是vue写的网页项目,为了最大化的减少工作量,调研后发现用electron+serialport满足需求,通过iframe加载已经写好的页面,再通过与iframe通信传输串口数据即可。但折腾来折腾去,踩了各种坑也花了接近两周的时间,刚好遇到疫情,就研究了一波,特此记录一下配置过程,主要是整合资源,将全过程记录。
安装 electron serialport electron-rebuild
安装electron受网络环境影响可能需要科学上网,不能科学上网就用cnpm。
mkdir my-electron-app && cd my-electron-app\
npm init
cnpm i electron --save-dev
cnpm i serialport
cnpm i electron-rebuild --save-dev
安装依赖
node-serialport是一个让node可以访问电脑串口设备的原生模块,需要编译,也是出问题最多的一个环节。编译需要做一些准备工作。
- 安装node-gyp、VS2017和python
npm install -g node-gyp
npm install --global --production windows-build-tools
npm config set python python2.7
npm config set msvs_version 2017
- 编译
.\node_modules\.bin\electron-rebuild.cmd
可能出现的问题
- 安装windows-build-tools时卡顿,此时一大神发现了解决方案,我按照此步骤,成功解决问题。
- NODE_MOUDLE_VERSION不一致,这个错误有可能在软件运行时抛出。
- 其他各种问题,只能百度,实在不行就google,多次尝试,我花了一周多的时间才搞好... 成功一次就别在瞎折腾了,放过在下也放过自己,我重新搞了一次,结果又遇到各种问题...
测试serialport
若当前无硬件设备,需要下载虚拟串口工具(VSPD虚拟串口)和串口调试工具。
package.json中将入口文件设置为main.js
// package.json
...
"main": "main.js"
...
添加main.js和html文件
在main.js添加测试代码,若控制台输出端口信息,则证明已经成功了95.8%了。
const serialport = require("serialport");
serialport.list().then((ports) => {
console.log(ports);
});
在html中使用serialport
上一步成功后,我们尝试将serialport用在html页面中,发现控制台会报错,经过查找各种资料,发现Electron 9.0开始,官方推荐在渲染进程中不使用原生nodejs模块,哦吼,所以我们该怎么办。
想到我们在main.js主线程上能用,那我们可以研究研究主线程和渲染线程的通信。Electron提供了ipcMain和ipcRenderer API,网上文章页讲的很详细,找了一份带有示例的与大家分享:Electron笔记之进程间通信(ipc)
- html页面设置串口参数:串口名称、波特率、校验位和停止位等参数,设置完将参数发送至主线程。
- 主线程接收参数,打开串口,接收数据(利用串口调试工具发送数据)。
- npm start启动项目,发现得到数据,成功!
const { ipcMain } = require("electron");
ipcMain.on("open-serialport", (event, args) => {
const port = new serialport(path, options, errorCallback);
port.on('data', data => {
// 将串口接收的数据返回渲染进程,用于显示
event.sender.send("send-data", `${data}`);
});
});
vscode对electron主线程调试
程序员怎么能不会调试呢!参照此篇文章进行调试。
打包
上面的都行的通之后,通过与iframe的通信便满足需求了。接下来研究怎么打包成安装包,因为还涉及到客户端的更新升级,在下用的electron-builder,安装完之后,在package.json添加打包命令,执行命令 npm run build 发现大量报错,一看都是网络原因,怎么办,不要怕,大神多的很,请参照electron-builder打包采坑问题汇总配置,一个字:好使!打包完后dist文件夹长这样,exe就是我们的安装程序了。
npm i electron-builder
// package.json
"build": {
"appId": "com.xxx.app",
"productName": "marco-test-app",
"publish": [
{
"provider": "generic",
"url": "http://localhost:7777/download",
"channel": "latest"
}
],
"mac": {
"target": [
"dmg",
"zip"
]
},
"win": {
"target": [
"nsis",
"zip"
]
},
"nsis": {
"oneClick": false,
"allowToChangeInstallationDirectory": true,
"allowElevation": true,
"createDesktopShortcut": true,
"createStartMenuShortcut": true,
"shortcutName": "marco-app"
}
},
"scripts": {
"start": "electron --inspect=8888 .",
"build": "electron-builder --win --x64"
},
自动更新 electron-updater
给了用户安装包,那必须得支持版本更新啊,我们怎么搞?
不要怕,electron也提供了更新策略,安装electron-updater,然后在main.js中检测更新,在package.json -> build -> publish中配置更新地址,为方便本地测试,我们用node在本地配置更新地址,可参考Electron应用实现自动更新 配置本地环境,打包的更新文件一定要放对位置,一定要有latest.yml文件,若不存在,需要在package.json -> build -> publish添加 "channel":"latest",配置完,安装软件后,如有高版本就会自动下载安装。
本地运行npm start测试更新时,可能会报错:dev-app-update.yml文件不存在或者Update for version X.X.X is not available (latest version: x.x.x, downgrade is disallowed),测试在本地建立此文件,将打包的文件夹win-unpacked\resources中app-update.yml内容复制过来即可,更多错误参考electron-updater更新electron应用程序。
npm i electron-updater
// main.js
app.whenReady().then(() => {
createWindow();
checkForUpdates();
});
function checkForUpdates() {
// 更新地址,即新版本存放地址
autoUpdater.setFeedURL("http://localhost:7777/download");
autoUpdater.checkForUpdates();
autoUpdater.on("update-available", function (info) {
dialog.showMessageBox({title: '更新', message: '有更新可用'});
});
autoUpdater.on('update-not-available', function (info) {
dialog.showMessageBox({title: '无更新', message: '无更新可用'});
})
autoUpdater.on("update-downloaded", (info) => {
dialog.showMessageBox(
{
// icon: __static + "/favicon.png",
type: "info",
title: "软件更新",
message: `已更新到最新版本(${info.version})请重启应用。`,
// detail: detail,
buttons: ["确定"],
},
(idx) => {
// 点击确定的时候执行更新
if (idx === 0) {
autoUpdater.quitAndInstall();
}
}
);
});
}
"build": {
"appId": "com.xxx.app",
"productName": "marco-test-app",
"publish": [
{
"provider": "generic",
"url": "http://localhost:7777/download",
"channel": "latest"
}
],
"mac": {
"target": [
"dmg",
"zip"
]
},
"win": {
"target": [
"nsis",
"zip"
]
},
"nsis": {
"oneClick": false,
"allowToChangeInstallationDirectory": true,
"allowElevation": true,
"createDesktopShortcut": true,
"createStartMenuShortcut": true,
"shortcutName": "marco-app"
}
}
总结
这一套流程下来,都要哭了,会遇到各种各样的问题,我一共花了接近两周时间(一天不到两小时)才搞好,太难了,中途想过放弃不搞了,但他越出错我越想搞,幸运的是最终成功了,不能保证按照这个流程一定成功,仅记录过程。
参考文章:
实战Electron使用SerialPort与串口交互详细全过程
npm安装windows-build-tools时卡在Successfully installed Python 2.7
electron使用serialport报错NODE_MOUDLE_VERSION不一致