jxTMS设计思想之web界面

110 篇文章 0 订阅
44 篇文章 0 订阅

jxTMS是以低成本快速定制为核心诉求的、SaaS模式的二次开发平台。本文是讲述jxTMS平台界面部分是如何设计的,整个系列请访问:jxTMS设计思想

基本设计思路

低成本定制是jxTMS设计的核心目标,jxTMS的所有设计都服从服务于此。上篇文章讲了jxTMS最核心的部件:功能点【capa】。界面以及后面要讲到的其它关键部件都依托、依存于capa。这是由于从低成本定制分解出的一个次级目标是热更新【hotUpdate】,笔者也是在近期才听说这个概念,所以在jxTMS中该功能叫做热机刷新。

jxTMS中的热机刷新有几个特点:

  • jxTMS平台中的各组织独立热机刷新,各组织之间相互隔离、互不影响

  • jxTMS的热机刷新是全体功能全部刷新,即将所有功能模块全部卸出,然后重新加载所有的功能模块定义,包括界面定义、数据类定义、数据源定义、入口定义和模块代码。一个组织的功能模块包括:平台内嵌的管理模块、用户自定义模块、第三方模块等

  • jxTMS的热机刷新非常简单:manager用户点击快捷栏中的【运维管理->重新加载】就可完成。哪怕有用户正在使用中都不受影响【当然,如果有了权限调整、增减了功能模块、业务功能有了升级,可能会导致正在使用中的用户因为前后的不一致产生困惑,所以如果是功能升级应尽量选择在没有用户使用时再升级】

清楚了jxTMS的热机刷新,大家可能就会理解为什么上面会说:界面以及后面要讲到的其它关键部件都依托、依存于capa了。就是为了拆卸模块时能拆得干干净净、清清楚楚,所以jxTMS需要尽可能的简化各部件间的逻辑关系。

回到界面的设计思想,低成本的一个关键就是尽可能的让一个开发者完成全部的开发任务。所以在界面方面,笔者的思路从一开始就非常明确:文本定义、json描述、动态绘制、极致简单

1、文本定义,即组成web界面的各控件在开发时是用文本进行定义的,一行一个控件,目前jxTMS提供了20多种控件,基本覆盖了用户交互的需要。

界面定义请参考:jxTMS在线编程手册之web界面中的相关说明

2、json描述,界面的文本定义在热机刷新【hotUpdate】时被加载,jxTMS将其解释为一个json对象。然后在用户请求显示该界面时,capa将该界面的json描述发送到web端

3、动态绘制,web端在接收到一个界面的json描述后,动态生成一个个的控件,然后将其组合为相应的界面,并根据json描述中的属性定义来调整该控件的显示效果

4、极致简单,在事件响应函数中,读写控件值各自就是一条命令:

#读用户在web控件中输入的数据
v = self.getInput('控件所绑定的数据名')

#输出数据到web控件
self.setOutput('控件所绑定的数据名',value)

#动态调整web控件的属性
self.setWOAttr('控件名',属性名,属性值)
同步还是异步

笔者下一个要解决的就是确定web端和后台capa之间的勾连模式:异步还是同步?!

大部分的web应用都采用的是同步模式,简单,语义直观。但笔者分析下来,jxTMS却无法采用同步模式,主要因为如下几点:

1、向用户显示一个界面是分为两步的:

  • 显示界面中的各组件

  • 必要时,为这些组件装定数据

但由于jxTMS的界面并非静态、而是在web端动态生成的,所以如果jxTMS工作在同步模式,就必须同时完成向前端输出界面的json描述和触发prepareDisp事件对界面进行数据装定。

但此时,界面还未生成,相关的映射关系都还未建立。如果要求同步则势必导致处理逻辑复杂化。

2、jxTMS的主界面中有一个动态工具条栏,用于放置当前用户在当前界面下可执行的业务操作。如下图:

企业微信应用

左上方的【日志】、【数据变动】、【用规则表检测】。

这些工具条不但是动态生成的,就连是否要向当前用户显示也是动态确定的:

  • 先根据当前用户的角色来确定用户是否有相应的操作权限,有权限才会显示、无权就看不到

  • 再根据当前的业务状态来确定有无必要向用户显示。如任务执行完毕,当然没必要也不应该再向用户显示【结束任务】

这里就出现一个问题:web必须在所有界面的初始化工作执行完毕后才能确定是否可以显示这些动态的工具条。但原则上界面又应在数据装定之前绘制完毕。

3、作为一个主要面向业务管理的二次开发平台,用户打开界面后,由于协同等的需要,动态刷新界面的需求是必须支持的,如几个销售同时执行某热销产品的销售作业时,需要实时刷新剩余库存。但web是无状态的、是一次性连接的。

总之,考虑到种种情况,笔者最终选择了异步模式来处理web界面和capa之间的交互过程。即整个web界面复杂的处理过程,不需要在一个disp请求中全部完成,而是分解为一系列的工作逐次进行:

  • 获取json描述

  • 动态绘制界面

  • 触发prepareDisp事件来装定界面数据

  • 动态特性处理,如工具条刷新、界面数据实时动态更新等

而这些工作完全可以乱序执行【当然不是完全的乱序,只是对顺序的要求不再如同步那般严格,从而导致难以调和的矛盾】。

既然是异步,那就存在一个问题:web端要通过轮询才能实现异步,这就会导致严重的性能问题。

jxTMS针对这个问题采取了一个折中的方式:轮询间隔逐步衰减。即在用户发起一个操作后,用一个很小的间隔【1秒】进行快速轮询,以快速同步前后端的数据与状态;然后逐步递增轮询间隔,直到一个最大间隔【64秒】后就慢速轮询,以维持前后端的数据交换不会中断。

当然,对于需要实时刷新数据的应用,过大的轮询间隔可能会导致刷新不够及时,jxTMS允许将轮询间隔保持在1秒的最小间隔处,直到该应用被关闭

多界面的异步兼容性

采用异步模式是因为jxTMS的动态界面所导致的不得以的妥协,虽然有了动态刷新界面数据等的额外好处,但带来的问题却更大。最严重的一个就是:多个界面的数据如何区分开?

这个问题在同步模式下根本不是问题,但在异步模式下却很严重:总不能每个界面就启动一个轮询吧?

jxTMS目前在主界面区允许同时打开5个界面、在辅助界面区允许同时打开10个界面,也就是说最多可以同时打开15个界面,如果每个界面一个轮询,那后端服务器的压力一下子就大了15倍,这就太过浪费了,因为绝大部分的轮询都没有数据需要交换。

所以jxTMS只保持了一个轮询来同时为所有界面的json解析、数据刷新等各种交互提供服务,

目前jxTMS保有10余种前后端的交互种类,如后端通知web端动态弹出一个消息框、全局消息广播等。而这些功能的存在,本就要求jxTMS的前后端保持一个长连接,如果不想采用webSocket,那就需要保持一个轮询线程,但这样的轮询,由于无法平衡性能与实时性的要求,是无法满足如动态弹窗这样的需求的

这样一来,jxTMS就需要从轮询数据流中为各界面提取出各自的数据。不过,jxTMS并未采取分流方式,在jxTMS的前端,所有的界面【包括5个主界面、10个辅助界面、快捷栏、菜单项】全部都是统一根据控件ID来管理的:

  • 有该ID的数据到来,就查找到该控件将相关数据转交给该控件自己去处理

  • 某控件用户有输入,则统一收集后一起发送到后端

后端也有一个对应的数据分发器,也是根据ID来分发数据,不关心该数据位于哪个capa中。

而在capa打开界面时,前后端分别建立相应的【ID-控件】映射关系;当capa卸出时【用户主动关闭界面;或相应界面区满后被动清除,如主界面区打开第6个界面时,会将最早打开的那个界面自动关闭】,前后端同时清除掉各自的【ID-控件】映射关系。

这样一来,当需要向web端的控件写入数据时:

#输出数据到web控件
self.setOutput('控件所绑定的数据名',value)

capa根据数据名从本功能点打开的所有控件中查找到相应的控件,然后用该控件的ID和相应数据组成一个json对象,然后同一个用户打开的所有capa统一将这些json对象收集后发送到web端,web端则根据各自的id进行数据的分发。

当用户在web控件中输入时,web端将所有用户的输入汇总后发送到后端,后端按控件id更新其所在capa中的数据缓存。则当用户读取数据时:

self.getInput('控件所绑定的数据名')

capa在自己的数据缓存中直接读数据名的数值即可。

目前jxTMS已经开放个人注册试用,欢迎大家注册试用:

注册到jxTMS

下面的系列文章讲述了如何用jxTMS开发一个实用的业务功能:

如何用jxTMS开发一个功能

下面的系列文章讲述了jxTMS的一些基本功能:

jxTMS的HelloWorld

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值