结识hybrid体验这一年

在这之前虽然看过一些博客介绍 hybrid,但是始终没有具体应用场景,想象的就是我现在做好了一个网站,然后 native 直接在 webview 中打开我的网站,类似浏览器中打开网站一样,头部添加一个类似浏览器的返回按钮,如果只是考虑到安卓或许这一步都没必要。

结识hybrid体验这一年

以下是以一个面描述了一个点的整个过程。

检索

通讯协议

远程操作

websocket 心跳重连问题

缓存方案

图片资源渲染问题

系统字体大小修改影响网页字体大小

多小程序扫同一个码的需求

认真接触 hybrid 是在入职后的第一个项目,项目是基于 Hybrid/webapp at gh-pages · yexiaochai/Hybrid · GitHub 其中视图部分在原项目基础上引入了 vue ,目录结构等都是和之前项目一致,页面和组件可以直接使用 vue 语法,hybrid 协议有些许变化。

没有 webpack 项目的启动依赖 Charles map local 预览项目,mock 工具当时使用的是 easy-mock 中间跨域的解决方案是 Charles map remote 。

硬件交互

我们常见的智能零售或者说其他的智能硬件的交互屏,一般是一个类似 树莓派 的板子,然后装载系统。可以是 win,android,也可以是 ios。开发需要 native 初始化一个 webview,然后定义一些通用协议,加载一个页面似乎就完活了。

通讯协议

开发过程中我们需要 native 赋予我们一些能力,我们需要约定一下通讯协议的格式,其中参数 tagname:协议名称;param:协议参数;callback:协议回掉(native处理成功以后可能需要返回一些参数信息) 。
格式如下:

{ tagname: '', // param: {}, callback() {} } 远程操作

例如用户扫码购买了一瓶饮料,我想在零售屏上切换一个欢迎使用的页面,这个时候需要在 用户-零售屏 上建立关系,这中间可能需要一个服务端。用户一开始和服务端建立联系,正常的下单购买,购买成功后,服务端推送一条消息给零售机,告诉他有用户买了瓶饮料,你现在给他推一个饮料出来。

用户 -> 扫码 -> 购买 -> 服务 -> 出货

用户扫描机器上的二维码,这个行为会触发一个与当前售卖机绑定的操作,绑定成功后服务可以推送一个消息给零售屏,零售屏接收到消息后会切换到欢迎界面,后续的交互包括支付成功,出货成功这些消息如果要表示到零售屏上都是同样的道理。用户与服务,服务与零售屏他们时如何通讯的呢?

用户与服务之间是数据请求,服务与零售之间为了通讯保持,建立的是 websocket 连接,零售机内部是 hybrid ,native 调用硬件能力。

问题分析

开发过程中遇见过一些问题,应该是 hybrid 应用开发也会遇到这些问题,相对而言这些问题对比一个成熟的 hybrid 方案要解决的问题要轻很多。

websocket 心跳重连问题

这个问题是消息推送相关。websocket 初始化会后,页面都是按照如下处理业务

const ws = new WebSocket('url'); ws.addEventListener('error', e => { // 去维护页面 }) ws.addEventListener('message', event => { // 按消息内容处理事件逻辑 }) ws.addEventListener('open', event => { // 定时发送消息 4min NAT }) ws.addEventListener('close', event => { // 去维护页面 }) ws.addEventListener('disconnect', event => { // 去维护页面 })

单页应用容器内维持状态,组件内展示业务状态。远程操作时提到的服务与零售屏之间的通讯是 websocket ,零售屏中通过监听 message 来调用对应的方法处理相应的逻辑。有指定的故障页面,故障会跳转到故障页面,故障有:机器断网(native捕捉处理),请求超时,服务端主动更新断开,运维维护断开等等情况,如果是 websocket 断开会定时刷新页面重新连接,如果是 websocket 没有断开,数据请求超时等,定时再次请求,如果请求成功切换页面。

这里有另外一个问题,零售屏页面更新的问题,之前是进入维护页面会定时刷新页面,这样如果页面更新下次刷新肯定可以更新到新的页面,现在更改成只有断开 websocket 才会刷新,这个断开操作可能会干扰到用户操作。
对于 app 来说有一个用户重启 app 的概念,我们也可以加一个这个功能,机器会断电,断电后可以更新或者线下运维人员可以在运维的时候重启一下。
还有一种方案就是服务向最近10分钟无状态的机器推送消息,机器收到消息后强制刷新页面。

定时发送业务心跳消息。在这之前没有定时去发送消息,会出现一种情况是受其他原因被关闭了,websocket 并不会监听到关闭或断开或错误,这样就不会去重新连接,这时用户的操作零售屏是收不到任何消息的。服务推送消息是正常推送会提示已经断开。 Pings have an opcode of 0x9, and pongs have an opcode of 0xA 心跳的发送都是底层协议来做的,但是会涉及到一个问题就是NAT超时链路会被断开,这个时候如果业务没有数据传递,客户端不会重新建立连接,如果零售屏没有消息发送就不能出发关闭时间,如果零售机就失联了,按照Android微信智能心跳方案设置了一个业务心跳,维持长链接的活动,这样以来不会触发用户扫码无响应机器失联的情况。
服务可以根据扫码加推送消息日志来判断有没有具体失联,如果失联可以调整业务心跳的触发时间。

缓存方案

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpyswf.html