阅读 717

Electron+serialport串口开发

前端开发利用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 复制代码

可能出现的问题

  1. 安装windows-build-tools时卡顿,此时一大神发现了解决方案,我按照此步骤,成功解决问题。

  2. NODE_MOUDLE_VERSION不一致,这个错误有可能在软件运行时抛出。

  3. 其他各种问题,只能百度,实在不行就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);   }); 复制代码

image.png

在html中使用serialport

上一步成功后,我们尝试将serialport用在html页面中,发现控制台会报错,经过查找各种资料,发现Electron 9.0开始,官方推荐在渲染进程中不使用原生nodejs模块,哦吼,所以我们该怎么办。 image.png

想到我们在main.js主线程上能用,那我们可以研究研究主线程和渲染线程的通信。Electron提供了ipcMain和ipcRenderer API,网上文章页讲的很详细,找了一份带有示例的与大家分享:Electron笔记之进程间通信(ipc)

  1. html页面设置串口参数:串口名称、波特率、校验位和停止位等参数,设置完将参数发送至主线程。

  2. 主线程接收参数,打开串口,接收数据(利用串口调试工具发送数据)。

  3. 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就是我们的安装程序了。

image.png

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"     }   } 复制代码

总结

这一套流程下来,都要哭了,会遇到各种各样的问题,我一共花了接近两周时间(一天不到两小时)才搞好,太难了,中途想过放弃不搞了,但他越出错我越想搞,幸运的是最终成功了,不能保证按照这个流程一定成功,仅记录过程。


作者:MarcoMa
链接:https://juejin.cn/post/7029236252557705252

文章分类
代码人生
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐