发明内容
本发明要解决的技术问题,在于提供一种本地多进程间数据订阅推送的方法,实现多个进程间的数据通信和数据共享,通用性高,灵活性好。
本发明是这样实现的:一种本地多进程间数据订阅推送的方法,将系统中的不同的进程通过加载相同的ActiveX组件实现各个进程间的通信;所述ActiveX组件包括:内存映射注册订阅信息、命名事件、命名管道;所述ActiveX组件之间通过内存映射实现注册、订阅信息的的共享,所述命名事件是对进程通知事件进行命名,所述命名管道是对进程数据通信管道进行命名;通过内存映射在多个进程间共享同一份注册订阅和信息;通过命名事件在不同进程之间相互通知及时更新注册订阅信息;通过命名管道由数据提供者主动向订阅者建立管道链接并推送数据。
进一步地,所述命名事件和命名管道采用同一个随机标识符GUID的字符串表示,系统中的进程每次启动都会重新随机获取一个标识符GUID用于命名系统的事件和管道;所有的命名管道都是基于报文的,保证命名管道每次收到的数据都是具有完整定义的报文。
进一步地,所述ActiveX组件还包括一个初始化接口、一个资源释放接口、一个数据推送接口以及一个数据接受回调事件;
初始化接口的参数包括:注册数据类型表、订阅数据类型表;该初始化接口用于初始化内存映射、注册进程信息、自动匹配建立进程间的数据供需关系;
资源释放接口:用于进程退出时清理进程注册信息以及进程间的供需关系更新;
数据推送接口的参数包括:数据类型、数据起始地址、以及数据大小;该数据推送接口用于推送进程能够提供的注册数据类型对应的数据,根据进程间数据供需关系进行广播推送;
数据接收回调事件的参数包括:数据类型、数据起始地址以及数据大小,该数据接收回调事件用于处理命名管道接收到的进程订阅的数据类型对应的数据。
进一步地,注册和订阅信息采用内存映射技术,依靠内存映射技术实现不同进程之间的共享,所述内存映射结构由注册信息、订阅信息、进程索引以及进程详情4部分组成;
所述注册信息用于登记每一种类型的数据都有哪些进程能够提供;其由M个结构单元T组成,每个结构单元从0开始顺序编号,取值范围为T0~TM-1,分别对应一种数据类型;每个结构单元T由个字节组成,P为进程数上限值;每个字节的每一位Tmi(0≤m≤M-1,0≤i≤7)代表一个进程的索引,值为1则表示该位索引对应的进程能够提供该数据,值为0则不能够提供该数据;其中,Tmi对应的进程索引编号为(m*8+i)的进程;
所述订阅信息的结构和注册信息是相同的,用于登记对应的数据类型都有哪些进程订阅了;同样由M个结构单元T组成,每个结构单元从0开始顺序编号,取值范围为T0~TM-1,分别对应一种数据类型;每个结构单元T由个字节组成,每个字节的每一位Tmi(0≤m≤M-1,0≤i≤7)代表一个进程的索引,值为1则表示该位索引对应的进程订阅该类型的数据,值为0则未订阅该类型的数据;其中,Tmi对应的进程索引编号为(m*8+i)的进程;
所述进程索引用于标识所述的进程详情中预分配的P个进程空间的使用情况,其大小为个字节,每个字节中的每一位Bij代表对应索引的进程空间使用情况;1表示已被占用,0则表示空闲;其中Bij(0≤i≤P-1,0≤j≤7)表示第i个字节的第j位,其对应的进程空间索引为(i*8+j);
所述进程详情用于存放每个进程对应命名管道和命名事件的名称,其大小为P*32个字节,每32个字节存储对应索引进程的命名管道和命名事件的名称;每个进程索引i对应的名称存储的相对进程详情的偏移地址为i*32;
内存映射大小的计算公式:内存映射大小S=注册信息+订阅信息+进程索引+进程详情
其对应计算公式为:
即为
进一步地,所述方法进一步包括初始化流程:初始化ActiveX组件获得标识符GUID创建命名事件和命名管道;创建订阅新型更新线程、命名管道监听线程、数据接收线程;判断内存映射是否存在;否,则创建并初始化内存映射;是,则初始化进程注册订阅信息,获取注册数据类型对应订阅进程的标识符GUID,并建立与所有标识符GUID对应的命名管道链接;绑定命名管道链接与订阅的数据类型的映射关系,从而完成初始化。
进一步地,所述更新注册订阅信息具体为:更新注册订阅信息,循环等待命名事件激活,判断线程是否退出,是,则线程退出并结束;否,则判断命名事件是否激活,否,则循环等待命名事件激活;是,则加载内存映射,获取注册数据类型对应订阅进程的标识符GUID;判断所有标识符GUID对应的命名管道是否已链接;否,与未链接的命名管道建立链接,并循环等待命名事件激活;是,判断所有已链接的命名管道的标识符GUID是否都存在,否,则关闭标识符GUID不存在的命名管道,并解除命名管道与数据类型的映射关系,并循环等待命名事件激活;是,则循环等待命名事件激活。
进一步地,所述推送数据具体为:查询订阅该类型的所有命名管道链接,判断查询结果是否为空,是,则推送结束并结束流程;否,判断查询是否遍历结束;是,则推送结束并结束流程;否获取下一个命名管道链接,推送数据。
进一步地,所述命名管道监听线程的监听流程具体为:循环等待客户端建立链接,判断线程是否退出,是,则推送结束并结束流程;否,则判断是否建立链接请求,否,则循环等待客户端建立链接,是,绑定通知消息并添加到客户端列表中;循环等待客户端建立链接。
进一步地,所述方法进一步包括数据接收流程:循环等待数据接收消息,判断线程是否退出,是,线程退出并结束流程;否,判断消息的数据是否到达,否,则循环等待数据接收消息,是,查询该消息绑定的所有客户端连接,判断查询结果是否为空,是,则循环等待数据接收消息,否,判断是否查询遍历结束,是,则循环等待数据接收消息;否,获取下一个命名管道链接,并接受数据,判断是否接收到数据,否,则重新判断是否查询遍历结束,是,通过回调时间通知处理接收数据。
进一步地,所述方法进一步包括退出流程:关闭订阅信息更新线程、命名管道监听线程、数据接收线程;将内存映射注册信息的所有类型中该进程索引对应的标志位置为0;将内存映射订阅信息的所有类型中该进程索引对应的标志位置为0,获取订阅数据类型对应数据提供进程的标识符GUID,并激活所有标识符GUID对应的命名事件,解除所有命名管道链接与订阅的数据类型的映射关系,关闭本进程所有猪洞建立的命名管道链接;回收进程索引,将内存映射中进程索引对应标志位置为0,判断是否所有进程均已退出,否,退出并结束,是,释放内存映射。
本发明具有如下优点:本发明在传统进程通信的基础上,通过订阅/推送技术,实现生产者(推送数据的进程)和消费者(接收数据的进程)间的分离和自动匹配,在配对的进程之间自动实现数据推送和广播,通用性高,灵活性好。特别适用于在不同系统进程之间进行数据通信和数据共享,能够有效降低后台系统进程管理复杂度和数据重复访问获取的压力。
具体实施方式
请参阅图1所示,本发明的一种本地多进程间数据订阅推送的方法,将系统中的不同的进程通过加载相同的ActiveX组件实现各个进程间的通信;所述ActiveX组件包括:内存映射注册订阅信息、命名事件、命名管道;所述ActiveX组件之间通过内存映射实现注册、订阅信息的的共享,所述命名事件对进程通知事件进行命名,所述命名管道是对进程数据通信管道进行命名;通过内存映射在多个进程间共享同一份注册订阅和信息;通过命名事件在不同进程之间相互通知及时更新注册订阅信息;通过命名管道由数据提供者主动向订阅者建立管道链接并推送数据。
其中,所述命名事件和命名管道采用同一个随机标识符GUID的字符串表示,系统中的进程每次启动都会重新随机获取一个标识符GUID用于命名系统的事件和管道;所有的命名管道都是基于报文的,保证命名管道每次收到的数据都是具有完整定义的报文。
所述ActiveX组件还包括一个初始化接口、一个资源释放接口、一个数据推送接口以及一个数据接受回调事件;
初始化接口的参数包括:注册数据类型表、订阅数据类型表;该初始化接口用于初始化内存映射、注册进程信息、自动匹配建立进程间的数据供需关系;
资源释放接口:用于进程退出时清理进程注册信息以及进程间的供需关系更新;
数据推送接口的参数包括:数据类型、数据起始地址、以及数据大小;该数据推送接口用于推送进程能够提供的注册数据类型对应的数据,根据进程间数据供需关系进行广播推送;
数据接收回调事件的参数包括:数据类型、数据起始地址以及数据大小,该数据接收回调事件用于处理命名管道接收到的进程订阅的数据类型对应的数据。
注册和订阅信息采用内存映射技术,依靠内存映射技术实现不同进程之间的共享,所述内存映射结构由注册信息、订阅信息、进程索引以及进程详情4部分组成;内存映射结构的结构如下表1所示:
表1
其大小主要取决于:数据类型个数M、最大进程上限数P。
所述注册信息用于登记每一种类型的数据都有哪些进程能够提供;其由M个结构单元T组成,每个结构单元从0开始顺序编号,取值范围为T0~TM-1,分别对应一种数据类型;每个结构单元T由个字节组成,P为进程数上限值;每个字节的每一位Tmi(0≤m≤M-1,0≤i≤7)代表一个进程的索引,值为1则表示该位索引对应的进程能够提供该数据,值为0则不能够提供该数据;其中,Tmi对应的进程索引编号为(m*8+i)的进程;
所述订阅信息的结构和注册信息是相同的,用于登记对应的数据类型都有哪些进程订阅了;同样由M个结构单元T组成,每个结构单元从0开始顺序编号,取值范围为T0~TM-1,分别对应一种数据类型;每个结构单元T由个字节组成,每个字节的每一位Tmi(0≤m≤M-1,0≤i≤7)代表一个进程的索引,值为1则表示该位索引对应的进程订阅该类型的数据,值为0则未订阅该类型的数据;其中,Tmi对应的进程索引编号为(m*8+i)的进程;
所述进程索引用于标识所述的进程详情中预分配的P个进程空间的使用情况,其大小为个字节,每个字节中的每一位Bij代表对应索引的进程空间使用情况;1表示已被占用,0则表示空闲;其中Bij(0≤i≤P-1,0≤j≤7)表示第i个字节的第j位,其对应的进程空间索引为(i*8+j);
所述进程详情用于存放每个进程对应命名管道和命名事件的名称,其大小为P*32个字节,每32个字节存储对应索引进程的命名管道和命名事件的名称;每个进程索引i对应的名称存储的相对进程详情的偏移地址为i*32;
内存映射大小的计算公式:内存映射大小S=注册信息+订阅信息+进程索引+进程详情
其对应计算公式为:
即为
其中,a)上述的数据类型:规定为所有的数据都可以用一个从0开始递增的编号唯一标识,用于区分不同的数据的定义;进程间通过该编号来确定自身能够提供的数据类型和需要订阅的数据类型;数据类型的上限是可变的,我们定义变量T用于表示数据类型个数的上限。
b)命名事件和命名管道的名称定义:命名事件和命名管道采用同一个随机标识符GUID的字符串表示,固定长度为32个字节。进程每次启动都会重新随机获取一个标识符GUID用于命名事件和管道;
c)基于报文的命名管道:所有的命名管道都是基于报文的,保证命名管道每次收到的数据都是具有完整定义的报文(区别于流式命名管道);
d)进程数上限:最大允许进行通信的进程数量。根据系统规模和系统复杂度的差异,通信的进程数量上限是可变的,我们定义变量P用于表示进程数上限。
e)数据报文结构:推送数据和接受数据的报文架构一样,都是由数据类型和数据内容组成,其中数据类型为放在报文的最前端,其大小等于随后紧跟数据内容。结构如下表2所示:
表2
f)推送数据的大小:由于命名管道推送数据报文的数据大小限制,当推送数据的大小大于报文上限时,进程之间必须自行协商数据分包发送机制,并自定义数据内容结构。
如图2所示,所述方法进一步包括初始化流程:初始化ActiveX组件获得标识符GUID创建命名事件和命名管道;创建订阅新型更新线程、命名管道监听线程、数据接收线程;判断内存映射是否存在;否,则创建并初始化内存映射;是,则初始化进程注册订阅信息,获取注册数据类型对应订阅进程的标识符GUID,并建立与所有标识符GUID对应的命名管道链接;绑定命名管道链接与订阅的数据类型的映射关系,从而完成初始化。
如图3所示,所述更新注册订阅信息具体为:更新注册订阅信息,循环等待命名事件激活,判断线程是否退出,是,则线程退出并结束;否,则判断命名事件是否激活,否,则循环等待命名事件激活;是,则加载内存映射,获取注册数据类型对应订阅进程的标识符GUID;判断所有标识符GUID对应的命名管道是否已链接;否,与未链接的命名管道建立链接,并循环等待命名事件激活;是,判断所有已链接的命名管道的标识符GUID是否都存在,否,则关闭标识符GUID不存在的命名管道,并解除命名管道与数据类型的映射关系,并循环等待命名事件激活;是,则循环等待命名事件激活。
如图4所示,所述推送数据具体为:查询订阅该类型的所有命名管道链接,判断查询结果是否为空,是,则推送结束并结束流程;否,判断查询是否遍历结束;是,则推送结束并结束流程;否获取下一个命名管道链接,推送数据。
如图5所示,所述命名管道监听线程的监听流程具体为:循环等待客户端建立链接,判断线程是否退出,是,则推送结束并结束流程;否,则判断是否建立链接请求,否,则循环等待客户端建立链接,是,绑定通知消息并添加到客户端列表中;循环等待客户端建立链接。
如图6所示,所述方法进一步包括数据接收流程:循环等待数据接收消息,判断线程是否退出,是,线程退出并结束流程;否,判断消息的数据是否到达,否,则循环等待数据接收消息,是,查询该消息绑定的所有客户端连接,判断查询结果是否为空,是,则循环等待数据接收消息,否,判断是否查询遍历结束,是,则循环等待数据接收消息;否,获取下一个命名管道链接,并接受数据,判断是否接收到数据,否,则重新判断是否查询遍历结束,是,通过回调时间通知处理接收数据。
如图7所示,所述方法进一步包括退出流程:关闭订阅信息更新线程、命名管道监听线程、数据接收线程;将内存映射注册信息的所有类型中该进程索引对应的标志位置为0;将内存映射订阅信息的所有类型中该进程索引对应的标志位置为0,获取订阅数据类型对应数据提供进程的标识符GUID,并激活所有标识符GUID对应的命名事件,解除所有命名管道链接与订阅的数据类型的映射关系,关闭本进程所有猪洞建立的命名管道链接;回收进程索引,将内存映射中进程索引对应标志位置为0,判断是否所有进程均已退出,否,退出并结束,是,释放内存映射。
另外,这里值得一提的是:
1、其他处理细节
a)进程注册订阅处理过程:1、查找内存映射中的进程索引,获取空闲进程控件索引i,将32位进程GUID字符串写入进程详情相对偏移地址为i*32的位置;2、将内存映射中注册信息中所有本进程注册数据类型对应的单元结构中第位置为1;3、将内存映射中订阅信息中所有本进程订阅数据类型对应的单元结构中第位置为1;4、根据订阅数据类型,查找提供该类型进程的GUID,并激活所有GUID对应的命名事件。
b)根据数据类型查找注册(订阅)进程的GUID过程:找到内存映射中数据类型对应的注册(订阅)信息中的单元结构,一次从第一个字节第一位开始逐位判断,如果第i个字节的第j位为1,则表示索引为(i*8+j)的进程注册(订阅)了该数据类型。
c)判断是否所有进程程均已退出的过程:依次判断内存映射中进程索引的所有字节,当所谓字节都为0,则表示所有进程均已退出。
总之,本发明通过基于内存映射技术的数据订阅,实现生产者(推送数据的进程)和消费者(接收数据的进程)间的分离和自动匹配,基于命名事件实现进程间的订阅更新通知,基于命名管道技术实现进程间定向数据推送,从而实现多个进程间的数据通信和数据共享,通用性高,灵活性好。特别适用于在不同系统进程之间的数据通信和数据共享,有效降低后台系统集成复杂度和数据重复访问获取的压力。
以上所述仅为本发明的较佳实施例,凡依本发明申请专利范围所做的均等变化与修饰,皆应属本发明的涵盖范围。