本文讲解4.4版jxTMS中的本地数据总线,整个系列的文章请查看:docker版jxTMS使用指南:4.4版升级内容
docker版本的使用,请查看:docker版jxTMS使用指南
4.0版jxTMS的说明,请查看:4.0版升级内容
4.2版jxTMS的说明,请查看:4.2版升级内容
4.4版jxTMS中增加了一个本地的数据总线。听起来似乎很高大上的,其实就是一种数据接收通知:源发送数据,感兴趣的接收方得到通知。既是一种数据交换机制,更是一种本机的、隔离的事件通知机制。
数据总线有两个参与方:
-
数据源:发送数据者
-
目标:对数据源发送的数据感兴趣者
数据源和目标之间没有任何约束,目标和目标之间也不存在约束与干扰。
引用:
from jx.jxLocalDataBus import jxLocalDataBus
jxLocalDataBus的类函数
registerSource(cls, type, source, siteType=None, siteName=None, varList={})
注册数据源
参数:type:数据源类型,如设备就使用自己的设备类型source:数据源名,如设备就使用自己的设备名siteType:数据源所在站点类型siteName:数据源所在站点名varList:如果是同质的数据源,可以用一个数据源来概括,这些数据源之间用不同的变量来区分,现在大家暂时可以不考虑
说明:如source是:ds-{id}。则代表了:ds-1,ds-2,ds-3,...。这是时数据源的区分就要用到varList:{'id':1}、{'id':2}、{'id':3}等等
unRegisterSource(cls, source)
取消数据源
参数:source:数据源名,如设备就使用自己的设备名
getInterestedVisitor(cls, str ,debug=False)
将字符串的判断表达式,即数据源的字符串形式,转换为判定式对象。也就是说,本地数据总线并不是单纯的数据广播,而是只通知那些根据此处的判断表达式判定对自己感兴趣的目标。
参数:str:数据源的字符串形式debug:是否打开调试
示例:表达式【t1.s1.v1】,是对设备类型【t1】设备名【s1】的变量【v1】感兴趣表达式【t1.s1:st2.sn2.v1】,是对位于站点类型【st2】的站点【sn2】中的设备类型【t1】设备名【s1】的变量【v1】感兴趣
registerTarget(cls, name, receiveFunc, interestedVisitorList)
注册感兴趣者的接收对象
参数:name:感兴趣者的名字receiveFunc:接收对象interestedVisitorList:用getInterestedVisitor得到的判定式的list
说明:receiveFunc的签名是:receiveFunc(sendObj,vn,v)#sendObj是发送数据时送入的发送者对象#vn是感兴趣的变量,v是源发送的数据
unRegisterTarget(cls, name)
取消接收对象
参数:name:感兴趣者的名字
inform(cls, sendObj, source, data)
发送数据通知
参数:sendObj:发送数据通知时的对象source:数据源名,如设备就使用自己的设备名data:数据
说明:发送的数据中,有的目标可能对某个数据感兴趣,有的可能对另外的数据感兴趣,甚至可能没人感兴趣,但这些和数据源没关系,目标之间也没有关系
目前,设备device类在初始化完毕后,会将自己注册为数据源:
jxLocalDataBus.registerSource(self._type,self._name,siteType=mySite.type(),siteName=mySite.name(),varList=self.varList())
并在接收到数据并处理完毕后,将其发送出来
jxLocalDataBus.inform(self,self._name,self._data)
所以,如果对某个设备的数据感兴趣,就可以注册一个目标来接收其发送的数据,如:
v = jxLocalDataBus.getInterestedVisitor('vrs20.vrs20-1.Level')
jxLocalDataBus.registerTarget('test1',recvVRSLevel,[v])
则当设备vrs20-1在接收到前端发送的潮位数据后,就可以在recvVRSLevel函数中接收到其处理后的潮位数据了,由于device在inform时把自身当做sendObj送出,所以recvVRSLevel函数中还可以调用sendObj.data()取到完整的设备数据。
数据投递的说明
当一个数据源做投递时,其行为逻辑是:
-
对所有对自己感兴趣的目标依次投递
-
对每一个目标,对其所有的判决式依次运行,如果有一个通过就投递给该目标并结束后继判决式的运行,然后转下一个对自己感兴趣的目标进行投递
有时,可能会同时对多个数据点产生兴趣,这就是用registerTarget注册目标时,interestedVisitorList是一个list的原因。
根据上述的投递行为逻辑,多个数据点时它们相当于or连接,只要有一个判决式成立,目标就会被触发,并收到第一个成立的数据。
所以当目标指定了自己对多个数据点有兴趣时,目标自身必须清晰的理解这一点:只要这些数据点中有一个得到了满足,自己就会得到通知。然后据此编写自己的处理逻辑。
概要之,数据总线,就是通知自己有了数据更新,感兴趣者可以收到更新后的数据,并得到一个触发的机会。
其优势在于收发双方、接收者之间,并没有任何严格的逻辑约束,具有较好的隔离性。也就是说,接收目标即便执行失败、掷出异常也不会产生任何影响。
参考资料:
jxTMS设计思想
jxTMS编程手册
下面的系列文章讲述了如何用jxTMS开发一个实用的业务功能:
如何用jxTMS开发一个功能
下面的系列文章讲述了jxTMS的一些基本开发能力:
jxTMS的HelloWorld