gmfe / Think

观麦前端团队的官方博客
68 stars 3 forks source link

称重(Electron)总结 #24

Open liyatang opened 6 years ago

liyatang commented 6 years ago

最近做了一个 Electron 项目,总结下。

Electron

称重需求需要对接硬件:智能电子秤(串口)和热敏打印机(usb)。 当然其他连接方式也是ok的,只是串口协议很简单。

为什么是 Electron?想象空间大很多,可以通过 node 获得极大的底层能力,相应 node 生态也成熟和丰富。

插曲:之前有看过 chrome app(有串口api),跑通了。但栽在打印那 part。打印两种方式:1 用chrome自带的打印,最终性能原因放弃。2 用 chrome app 提供蓝牙 api,直接使用热敏打印机的打印协议,此方案没跟进,毕竟蓝牙模块不是什么机器都有。 打印不展开,具体见 打印相关总结

Electron web

没有采用常规的离线代码形式,而是直接用线上代码,灵活迭代优先。当然官网不建议,因为会有安全问题,代码可随时获得系统能力。但离线形式更新时被截获一样是有安全问题。安全这块暂时没有考虑太多。

升级方案

Electron 的 web 和 普通浏览器不一样,用户刷新不会这么频繁,而是启动的时候是那个版本就在哪个版本了,除非重启。如果版本发布,用户不会立即使用到,需要提醒用户更新。

打包线上代码把 package.json 一同打出去,同时通过 webpack 把 version 打进 代码内,这样打开应用时定时去拉去 package.json 文件来判断版本更新。如果更新,就引导用户重启。(可以直接reload刷新的,为了营造一种 pc 应用错觉,故意重启)

电子智能称,通过串口接入电脑。串口涉及波特率,数据协议等等,就不具体展开了。默认波特率是 9600,频率特别高。如果在监听数据变更的事件内做复杂逻辑的话,就会把 js 卡死。

一开始在监听函数内做数据处理逻辑,比如拼接过滤处理反转等逻辑,就会把 js 卡的有点死,后来引入buffer,函数内仅仅存储到 buff(array.push 一个操作),同时在另起一条线去读取处理数据,大大提升了性能。

可能会想到 throttle。因为电子秤推送数据不是单个可用,即要拼接起来才能用(不同厂商不一样,有些厂商规范很多),所以 throttle 不可用。

btw,像这种由硬件(node 封装的 c)推送的数据内的函数貌似不能断点的,哪怕我 debugger 中,还是会不停的运行打印数据。 没有深入了解,感觉是 c 推送的优先级搞?懂的给点提示。

打印

打印用 Electron 提供的 api,也遇到了些问题。 (浏览器自带的打印有确认框,需人工介入,Electron 有静默打印功能)

1 批量打印。会丢,经过测试间隔 1s 再引入缓冲后可解决。 至于内部的机制没太了解。btw,一开始用了轮询缓冲方式,会导致打印延迟 0 ~1000ms,所以轮询方式不好。 2 打印的是标签,只有一个区域供打印,如果内容多了会导致打多张浪费。 用了固定高宽+ overflow。单位是 cm。

关于打印,本身有很多基本的css,关键的是 @page @media print,具体不展开。

setTimeout setInterval

以前倒是没发现还是有挺多思考点的。

setInterval 不建议用,我更多需求的是每隔 Ns,如果有次运行了很久,会导致后面的挨的进。

那 setTimeout 模拟 setInterval。 两种实现

// 1 会遇到和 setInterval 一样的问题
function fun(){
    setTimeout(fun, 1000);

    console.log('do something');
}

func();

// 2
function fun(){
    console.log('do something’);

    setTimeout(fun, 1000);
}

func();

// but,如果 do something 有报错会终止,于是 try catch 下。
function fun(){
    try{
        console.log('do something');
    }catch(){}

    setTimeout(fun, 1000);
}

electron require

require 和 window.require 是有区别的。

Electron 会识别出 require,但是被 webpack build 转换掉。 写 window.require 即可。

壳接口层

基于 Electron,大部分内容还是web,可以扩展到其他壳上,比如 Electron Chrome RN 等,这时需要封装下,让 web 不关心壳。

btw, 不同的壳行为不一样,有些难以发现,需要限制 web 的使用,只能通过封装的调用。 比如 window.open。

野狗数据同步

如果多台机器同时作业,数据需要同步。 那么自己搭实时通信能力不显示。就借助了野狗云。 一个第三方的应用,就需要隔离的非常好。绝对不能因为第三方服务的稳定性而影响。so,事件,用来解耦再合适不过了。 同时对同步过来的数据做好校验做好校验做好校验。