CN114979233A - 基于域套接字实现模块间同步和异步调用的方法和系统 - Google Patents
基于域套接字实现模块间同步和异步调用的方法和系统 Download PDFInfo
- Publication number
- CN114979233A CN114979233A CN202210847825.1A CN202210847825A CN114979233A CN 114979233 A CN114979233 A CN 114979233A CN 202210847825 A CN202210847825 A CN 202210847825A CN 114979233 A CN114979233 A CN 114979233A
- Authority
- CN
- China
- Prior art keywords
- message
- module
- client
- server
- request
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Pending
Links
- 238000000034 method Methods 0.000 title claims abstract description 85
- 230000001360 synchronised effect Effects 0.000 title claims abstract description 45
- 230000004044 response Effects 0.000 claims abstract description 74
- 238000012545 processing Methods 0.000 claims abstract description 48
- 230000008569 process Effects 0.000 claims description 41
- 230000000977 initiatory effect Effects 0.000 claims description 7
- 238000004883 computer application Methods 0.000 abstract description 2
- 230000006870 function Effects 0.000 description 43
- 238000004891 communication Methods 0.000 description 8
- 101100257062 Leishmania major IPCS gene Proteins 0.000 description 6
- 238000012790 confirmation Methods 0.000 description 3
- 238000007781 pre-processing Methods 0.000 description 3
- 230000003068 static effect Effects 0.000 description 3
- 238000012544 monitoring process Methods 0.000 description 2
- 238000004806 packaging method and process Methods 0.000 description 2
- 230000009286 beneficial effect Effects 0.000 description 1
- 230000008901 benefit Effects 0.000 description 1
- 230000005540 biological transmission Effects 0.000 description 1
- 125000004122 cyclic group Chemical group 0.000 description 1
- 238000001514 detection method Methods 0.000 description 1
- 230000000694 effects Effects 0.000 description 1
- 238000005538 encapsulation Methods 0.000 description 1
- 230000006872 improvement Effects 0.000 description 1
- 230000003993 interaction Effects 0.000 description 1
- 230000007774 longterm Effects 0.000 description 1
- 230000015654 memory Effects 0.000 description 1
- 230000004048 modification Effects 0.000 description 1
- 238000012986 modification Methods 0.000 description 1
- 239000011800 void material Substances 0.000 description 1
Images
Classifications
-
- H—ELECTRICITY
- H04—ELECTRIC COMMUNICATION TECHNIQUE
- H04L—TRANSMISSION OF DIGITAL INFORMATION, e.g. TELEGRAPHIC COMMUNICATION
- H04L69/00—Network arrangements, protocols or services independent of the application payload and not provided for in the other groups of this subclass
- H04L69/16—Implementation or adaptation of Internet protocol [IP], of transmission control protocol [TCP] or of user datagram protocol [UDP]
- H04L69/161—Implementation details of TCP/IP or UDP/IP stack architecture; Specification of modified or new header fields
- H04L69/162—Implementation details of TCP/IP or UDP/IP stack architecture; Specification of modified or new header fields involving adaptations of sockets based mechanisms
Landscapes
- Engineering & Computer Science (AREA)
- Computer Security & Cryptography (AREA)
- Computer Networks & Wireless Communication (AREA)
- Signal Processing (AREA)
- Computer And Data Communications (AREA)
Abstract
本申请提出一种基于域套接字实现模块间同步和异步调用的方法和系统,属于计算机应用技术领域,方法包括:服务器创建域套接字并侦听连接请求;当侦听到客户端模块的连接请求时,服务器接受连接,并对所属模块进行鉴别,鉴别通过后并进入消息转发状态;异步接收客户端A请求消息,通过客户端A请求消息中包含的目标模块实例的域套接字,将消息发送到目标模块,实现消息的路由转发;接收目标模块的响应消息,并将所述响应消息发送到客户端A,完成一次同步调用。本申请提高了数据收发的效率,避免了基于TCP/IP套接字的网络协议处理开销,避免了临时实例到最终实例的切换所带来的效率损失和不稳定因素。
Description
技术领域
本申请属于计算机应用技术领域,具体涉及一种基于域套接字实现模块间同步和异步调用的方法和系统。
背景技术
在一个计算机系统中,往往由多个进程组成,进程之间相互协作,共同实现一个系统功能。在计算机系统中,提供了丰富的进程间通信的方式,例如管道、命名管道、消息队列、共享内存、信号量、套接字等,但这些都是基础的通信方法,并不能提供简单直接的进程间同步和异步调用的方法,现有技术中往往需要开发者进行大量的程序开发。此外也有操作系统级的远程调用方法,例如window平台下的远程调用服务、COM接口等,这些往往在window下使用,而且普及率不是很高,系统依赖和开销也比较大,而且无法在linux系统下应用。另外基于互联网的远程调用系统,例如webservice,是为网络分布式应用所开发的平台,同样需要http服务器的介入,系统开销大,不太适用于单机系统下的效率要求。
发明内容
基于以上技术问题,本申请提供了一种基于域套接字实现模块间同步和异步调用的方法和系统。
第一方面,本申请提出一种基于域套接字实现模块间同步和异步调用的方法,包括如下步骤:服务器创建域套接字并侦听连接请求;当侦听到客户端模块的连接请求时,服务器接受连接,并对所属模块进行鉴别,鉴别通过后并进入消息转发状态;异步接收客户端A请求消息,通过客户端A请求消息中包含的目标模块实例的域套接字,将消息发送到目标模块,实现消息的路由转发;接收目标模块的响应消息,并将所述响应消息发送到客户端A,完成一次同步调用。
所述服务器创建域套接字并侦听连接请求,包括如下步骤:服务器启动服务进程;根据系统中的模块编号和数量,初始化对应的模块实例单元;创建服务器中用于侦听的域套接字;进入循环侦听模式,等待各个模块的连接请求。
所述创建服务器中用于侦听的域套接字,包括:创建一种基于AF_UNIX的域套接字用于侦听连接请求,将创建的域套接字,绑定到约定的域名称,并且设置为异步模式。
所述创建服务器中用于侦听的域套接字,包括:基于异步域套接字,循环初始化套接字句柄,并调用套接字select方法,侦听来自各个模块的连接请求;当等待超时后,继续下一次循环select方法。
所述当侦听到客户端模块的连接请求时,服务器接受连接,并对所属模块进行鉴别,鉴别通过后并进入消息转发状态,包括如下步骤:所述当侦听到一个模块的连接请求时,创建一个域套接字,设置为异步模式,并用所述套接字接受来自模块的连接请求;在域套接字连接请求的附属信息中,包括发起连接请求模块的模块ID和模块名称;通过所述模块ID和模块名称进行鉴别;当鉴别通过后,将通过模块ID直接索引到模块实例,并将所述模块实例转为消息转发状态;对所属模块进行鉴别,鉴别通过后并进入消息转发状态。
所述当侦听到客户端模块的连接请求时,服务器接受连接,并对所属模块进行鉴别,鉴别通过后并进入消息转发状态,包括:当采用select方法检测到有套接字句柄数据接收时,检测各个套接字是否存在数据于套接字缓冲区,如果存在则进入消息转发状态,如果不存在,则跳过所述套接字。
所述异步接收客户端A请求消息,通过客户端A请求消息中包含的目标模块实例的域套接字,将消息发送到目标模块,实现消息的路由转发,包括:异步接收客户端请求消息;对接收到的请求消息进行长度判断,若接收数据达到消息头部长度,则长度检查通过;若检测消息头部中数据是消息头部的魔鬼字,则读取消息长度信息,并根据所述长度信息判断是否接收到完整的消息数据,若消息数据完整,则检查完整性通过;若通过长度检查以及完整性检查时,则表明所述消息为正确且完整;若没有通过长度检查或完整性检查其中一项或两项时,则表明所述消息为不正确的;将所述消息提交给消息路由转发函数进行处理;消息路由转发函数根据消息的目标模块ID,直接索引到目标模块实例,并通过目标模块实例中的域套接字将消息发送出去,实现消息的路由转发过程;在消息转发完成后,将所述消息长度信息从缓冲区清除,并继续判断是否有下一条消息直到处理完缓冲区内所有的消息。
所述异步接收客户端A请求消息包括:当客户端A模块需要同步调用另外客户端B一个模块的某个功能时,则向服务器发送请求消息;进入一个循环等待响应的过程,若等待超时则返回超时错误;若收到客户端B目标模块的响应消息则进入下一步处理;将收到的响应消息中的数据拷贝到调接收缓存,并向返回成功的结果;根据消息类型对响应数据进行相应的处理,完成一次同步调用。
所述完成一次同步调用包括:将完成一次同步调用过程封装到一个接口函数中,供模块调用。
所述完成一次同步调用包括:将完成一次同步调用过程中发送请求和接收响应接口函数提供给模块分别调用,实现模块间的异步调用;所述接收目标模块的响应消息,包括如下步骤:客户端B启动各个模块,调用初始化函数,创建客户端B模块的域套接字,并向所述服务器发起连接请求;同步接收服务器发送的消息,并根据消息类型分发到对应的消息队列;循环接收服务器发送的消息并分发到对应的消息队列,在接收到服务器发送的消息后调用所述初始化函数处理消息,并发送响应消息到所述服务器。
所述调用初始化函数,创建客户端B模块的域套接字,包括:各个模块调用初始化函数时,同步传入模块的ID号、模块名称和模块的消息处理函数句柄;所述模块ID和模块名称将用于告知服务器发起连接请求的身份,消息处理函数句柄用于接收到消息后,调用所述函数句柄完成消息的处理。
所述向所述服务器发起连接请求,包括:当模块发起连接请求时,通过域套接字的sun_path字段,携带模块ID和模块名称信息,为首次连接获知模块ID。
所述同步接收服务器发送的消息包括:同步读取接收服务器发送的消息的域套接字,并检测读取到数据的长度、消息标识魔鬼字;根据消息的类型,将消息发送到对应的消息队列;对于响应类消息,则发送到响应消息队列,由本模块的发送请求后正在等待响应的函数接收并处理;对于请求类消息,则发送到请求消息队列,由消息调度处理线程调度处理。
所述客户端A与客户端B为系统的同一个客户端,客户端A与客户端B视为为同一个客户端的不同模块。
第二方面,本申请提出了一种基于域套接字实现模块间同步和异步调用的系统,包括:第一模块、第二模块、第三模块、第四模块;所述第一模块用于服务器创建域套接字并侦听连接请求;所述第二模块用于当侦听到客户端模块的连接请求时,服务器接受连接,并对所属模块进行鉴别,鉴别通过后并进入消息转发状态;所述第三模块用于异步接收客户端A请求消息,通过客户端A请求消息中包含的目标模块实例的域套接字,将消息发送到目标模块,实现消息的路由转发;所述第四模块用于接收目标模块的响应消息,并将所述响应消息发送到客户端A,完成一次同步调用。
所述第三模块包括:第一单元、第二单元、第三单元、第四单元;所述第一单元用于当客户端A模块需要同步调用另外客户端B一个模块的某个功能时,则向服务器发送请求消息;所述第二单元用于进入一个循环等待响应的过程,若等待超时则返回超时错误;若收到客户端B目标模块的响应消息则进入下一步处理;所述第三单元用于将收到的响应消息中的数据拷贝到接收缓存,并向返回成功的结果;所述第四单元用于根据消息类型对响应数据进行相应的处理,完成一次同步调用。
所述第四模块,包括:第五单元、第六单元、第七单元;所述第五单元用于客户端B启动各个模块,调用初始化函数,创建客户端B模块的域套接字,并向所述服务器发起连接请求;所述第六单元用于同步接收服务器发送的消息,并根据消息类型分发到对应的消息队列;所述第七单元用于循环接收服务器发送的消息并分发到对应的消息队列,在接收到服务器发送的消息后调用所述初始化函数处理消息,并发送响应消息到所述服务器。
有益技术效果:通过域套接字进行进程间的数据收发,避免了基于TCP/IP套接字的网络协议处理开销,提高了数据收发的效率。通过对域套接字连接请求时所附带的sun_path信息,实现了连接即可识别请求模块,进一步实现了从连接开始即可通过模块ID实现对模块实例的直接索引,避免了临时实例到最终实例的切换所带来的效率损失和不稳定因素,同时通过直接索引目标实例实现的快速查找。本申请还通过请求和响应两个消息队列的分发处理,巧妙的实现的本模块同步异步调用和响应其他模块请求及发送响应的并行处理而且各不影响。
附图说明
图1为本申请实施例一种基于域套接字实现模块间同步和异步调用的方法流程图;
图2为本申请实施例一种基于域套接字实现模块间同步和异步调用的系统。
具体实施方式
下面结合附图对本申请作进一步描述。以下实施例仅用于更加清楚地说明本发明的技术方案,而不能以此来限制本申请的保护范围。
本申请基于域套接字实现单机内或不同客户端之间进程间的数据高效率交换,并通过对消息收发的封装处理,不同模块(进程)间的消息路由,请求和发送消息队列管理,实现简单高效的模块间异步和同步调用的方法。
现有技术中,根据连接启动的方式以及本地套接字要连接的目标,套接字之间的连接过程可以分为三个步骤:(1)服务器侦听。(2)客户端请求。(3)连接确认。
(1)服务器侦听:所谓服务器侦听,是指服务器端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态。
(2)客户端请求:所谓客户端请求,是指由客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套接字的地址和端口号,然后就向服务器端接字提出连接请求。
(3)连接确认:所谓连接确认,是指当服务器端套接字侦听到或者说接收到客户端套接字的连接请求,就会响应客户端套接字的请求,建立一个新的线程,并把服务器端套接字的描述发送给客户端。一旦客户端确认了此描述,连接就建立好了。而服务器端套接字继续处于侦听状态,接收其他客户端套接字的连接请求。
第一方面,本申请提出一种基于域套接字实现模块间同步和异步调用的方法,如图1所示,包括如下步骤:步骤S101:服务器创建域套接字并侦听连接请求;步骤S102:当侦听到客户端模块的连接请求时,服务器接受连接,并对所属模块进行鉴别,鉴别通过后并进入消息转发状态;步骤S103:异步接收客户端A请求消息,通过客户端A请求消息中包含的目标模块实例的域套接字,将消息发送到目标模块,实现消息的路由转发;步骤S104:接收目标模块的响应消息,并将所述响应消息发送到客户端A,完成一次同步调用。
所述服务器创建域套接字并侦听连接请求,包括如下步骤:步骤S101.1:服务器启动服务进程;步骤S101.2:根据系统中的模块编号和数量,初始化对应的模块实例单元;本实施例中在服务进程启动时,根据本系统模块编号和数量,是以静态变量的形式初始化对应的模块实例单元。
typedef struct{
int run_flg; // 系统运行标记,用于控制服务端是否继续运行
int listen_fd; // 服务端用于侦听连接请求的域套接字
int max_fd; // 用于域套接字模型中,fd_setfd_sets; //
IPCS_CLIENT_ST clients[MODULE_END]; // 根据本系统模块编号和数量定义模块实例单元,MODULE_END即指模块最大数量的宏定义}IPCS_SRV_ST;IPCS_SRV_ST * ipcs_get_srv(){
static IPCS_SRV_ST s_socket_srv = {0}; // 以函数静态变量的形式生成了服务端和服务端所含客户端实例单元的存储区域,并全部初始化为零。一方面避免全局变量,一方面避免动态生成可能带来的意外释放的风险,提高系统稳定性;
return &s_socket_srv;}步骤S101.3:创建服务器中用于侦听的域套接字;步骤S101.4:进入循环侦听模式,等待各个模块的连接请求。
本实施例创建服务器端用于侦听模块端介入的域套接字。并进入循环侦听模式,等待各个模块的连接请求;同时也检测已经连接模块的数据通信请求,即一个select即负责连接侦听,也负责数据通信检测:while(pSrv->run_flg){ // 根据运行标记,循环执行,直到该标记被修改为停止状态,即系统停止timeout.tv_sec = SELECT_WAITING_TIME_S; //设置本次select的等待时间timeout.tv_usec = 0;ipcs_update_fdset(); // 根据套接字通信的要求,重置所有的套接字句柄readsocks = select(pSrv->max_fd+1, psets, (fd_set *) NULL, (fd_set *) NULL, &timeout)//调用select方法检测是否有连接请求和通信数据发生于任何域套接字句柄if(readsocks> 0){ // 表明套接字有连接或者数据通信事件发生if (FD_ISSET(pSrv->listen_fd,psets)) // 单独判断是否有连接请求发生ipcs_on_accept(pSrv->listen_fd); // 处理连接请求for(i = 0; i< MODULE_END ; i++){ // 单独依次个模块判断是否有数据通信发生if (FD_ISSET(pSrv->clients[i].fd,psets))ipcs_on_recive(&pSrv->clients[i]); // 接收并处理对应域套接字的数据
}}所述创建服务器中用于侦听的域套接字,包括:创建一种基于AF_UNIX的域套接字用于侦听连接请求,将创建的域套接字,绑定到约定的域名称,并且设置为异步模式。
所述创建服务器中用于侦听的域套接字,包括:基于异步域套接字,循环初始化套接字句柄,并调用套接字select方法,侦听来自各个模块的连接请求;当等待超时后,继续下一次循环select方法。这样实现的目的是放在系统长时间卡死在select方法中,无法确定系统是否依然运行正常,同时域套接字采用异步select模型最大的好处在于,但单线程并发异步处理多个客户端模块的套接字连接和通信请求,系统运行效率高。
所述当侦听到客户端模块的连接请求时,服务器接受连接,并对所属模块进行鉴别,鉴别通过后并进入消息转发状态,包括如下步骤:步骤S102.1:所述当侦听到一个模块的连接请求时,创建一个域套接字,设置为异步模式,并用所述套接字接受来自模块的连接请求;步骤S102.2:在域套接字连接请求的附属信息中,包括发起连接请求模块的模块ID和模块名称;步骤S102.3:通过所述模块ID和模块名称进行鉴别;步骤S102.4:当鉴别通过后,将通过模块ID直接索引到模块实例,并将所述模块实例转为消息转发状态;步骤S102.5:对所属模块进行鉴别,鉴别通过后并进入消息转发状态。
具体实现过程为:域套接字连接请求信息中包含模块ID号和模块名称,通过对比模块ID否是服务端允许的ID号,服务端预设定一个合法的模块ID列表;如果鉴别通过,则进入消息转发状态;如果鉴别不通过,则关闭域套接字连接请求。
本实施例当侦听到模块的连接请求时,接受连接,并对所属模块进行鉴别,鉴别通过后并进入消息转发状态;client_fd = accept(listenfd, (struct sockaddr *)&un, &len); // 接受域套接字连接if (client_fd< 0) return;ret = uds_nonblock(client_fd, 1); // 设置为异步模式if (ret < 0) {close(client_fd);return;}pMidStr = strrchr(un.sun_path,'.'); // 获取连接请求时所携带的信息if(NULL != pMidStr){pMidStr[0] = '\0'; // 拆分携带信息中的模块名称和模块IDpMidStr++;mid = atoi(pMidStr); // 获得并转换模块IDpClient = ipcs_get_client(mid); // 根据模块ID,直接索引到模块实例if(NULL != pClient){ // 如下计划将模块信息保存到实例中,并将实例状态改为‘连接’pClient->fd = client_fd;pClient->mid = mid;pClient->state = CLIENT_STATE_CONNECTED;strncpy(pClient->mname, un.sun_path, MOD_NAME_LEN);return;}else close(client_fd); //关闭不合法的连接请求}通过模块ID直接索引到模块实例,是保证系统运行高效的一种方式。它比大家常规采用连表存储结构和基于连表的查找方法,无论是查找效率还是程序的长期可靠性都高出很多;所述当侦听到客户端模块的连接请求时,服务器接受连接,并对所属模块进行鉴别,鉴别通过后并进入消息转发状态,包括:当采用select方法检测到有套接字句柄数据接收时,检测各个套接字是否存在数据于套接字缓冲区,如果存在则进入消息转发状态,如果不存在,则跳出所述套接字。
所述异步接收客户端A请求消息,通过客户端Aaron请求消息中包含的目标模块实例的域套接字,将消息发送到目标模块,实现消息的路由转发,包括:步骤S103.1:异步接收客户端请求消息;步骤S103.2:对接收到的请求消息进行长度判断,若接收数据达到消息头部长度,则长度检查通过;其中,一个完整的消息包括各种数据,因为是异步套接字,每次不能确保一定收到了一个完整的消息,所以需要不断接收,直到一个完整的消息包含数据接收完成。也可能一次性收到了几个完整的消息。
步骤S103.3:若检测消息头部中数据是消息头部的魔鬼字,则读取消息长度信息,并根据所述长度信息判断是否接收到完整的消息数据,若消息数据完整,则检查完整性通过;步骤S103.4:若通过长度检查以及完整性检查时,则表明所述消息为正确且完整;若没有通过长度检查或完整性检查其中一项或两项时,则表明所述消息为不正确的;步骤S103.5:将所述消息提交给消息路由转发函数进行处理;步骤S103.6:消息路由转发函数根据消息的目标模块ID,直接索引到目标模块实例,并通过目标模块实例中的域套接字将消息发送出去,实现消息的路由转发过程;步骤S103.7:在消息转发完成后,将所述消息长度信息从缓冲区清除,并继续判断是否有下一条消息直到处理完缓冲区内所有的消息。
步骤S103的实施例以Select模型循环检测是否有来自模块的消息,接收并检查消息的完整性,然后根据消息的目标模块,索引到目标模块实例,通过目标模块实例的域套接字,将消息发送到目标模块,实现消息的路由转发:len = uds_read(pClient->fd, &pClient->buff); // 读取域套接字接收到的数据if(len> 0){while(len> 0){ // 一次可能接收多条消息,所以循环处理每一条len = uds_check_msg(&pClient->buff); // 对接收到的数据进行检测,确认消息完整if(len> 0){ipcs_msg_rpoc(pClient); // 调用消息处理函数,完成消息路由转发uds_buff_clean(&pClient->buff, len); // 将处理完的消息,从缓冲清楚}}}消息路由转发处理:void ipcs_msg_rpoc(IPCS_CLIENT_ST *pClient){// 省略部分预处理代码pDstClient = &(pSrv->clients[pMsg->header.dst]); // 根据消息的目标模块ID,直接索引到对应实例if(CLIENT_STATE_OPPERATION == pDstClient->state){dataLen = (IPC_MSG_HEADER_LEN + pMsg->header.dataLen);wrLen = uds_write(pDstClient->fd, (char *)pMsg, dataLen); //将数据发送到目标模块实例if(IPC_ERROR == wrLen&& EPIPE == errno){ // 发送出错的异常处理pDstClient->state = CLIENT_STATE_STOP;close(pDstClient->fd);pDstClient->fd = 0;}}所述异步接收客户端A请求消息包括:步骤S201:当客户端A模块需要同步调用另外客户端B一个模块的某个功能时,则向服务器发送请求消息;本步骤实施例为:当模块需要同步调用另外一个模块的某个功能时,将向目标模块发送请求消息:int ipc_get_exec(int module, int userMsg , unsigned char *snd_buf, unsignedint snd_len, int *rc){// 省略部分预处理代码if(IPC_MSG_MAX_DATA_LEN >snd_len){msg.header.dst = module; //目标模块IDmsg.header.ipcMsg = PROTO_REQUEST; //标记为请求消息msg.header.userMsg = userMsg; //用户自定义的消息类型msg.header.dataLen = snd_len; //消息的长度memcpy(msg.header.data, snd_buf, snd_len);ret = ipcc_post_msg(&msg); //发送消息if(ret > 0){tci = msg.header.tci;memset(&msg, 0, sizeof(msg));ret = ipcc_waiting_ack(pSelf, tci, &msg); // 等待对方的回应}}if(NULL != rc)*rc = ret;return ret;}发送消息:int ipcc_post_msg(IPC_MSG_ST * pMsg){// 省略部分预处理代码pMsg->header.msgFlg = IPC_MSG_FLG; //消息魔鬼字pMsg->header.tci = ipcc_get_msg_tci(pSelf); //生成一个消息会话ID,用于标识一个请求和回应的对应关系pMsg->header.src = pSelf->mid; //源模块IDpthread_mutex_lock(&pSelf->mutex); //多线程并发,加锁ret = uds_write(pSelf->fd, (char *)pMsg, (IPC_MSG_HEADER_LEN + pMsg->header.dataLen));//发送pthread_mutex_unlock(&pSelf->mutex); //多线程并发,解锁return ret;}步骤S202:进入一个循环等待响应的过程,若等待超时则返回超时错误;若收到客户端B目标模块的响应消息则进入下一步处理;本步骤实施例为:请求消息发送完成后,将进入一个循环等待响应的过程,直到收到对应的消息,或者超时:for(i=0; i< IPC_WITING_RSP_LOOP; i++){ // 循环等待,直到循环等待超时usleep(USLEEP_TIME_10MS); // 休眠10毫秒,避免CPU消耗ret = msgrcv(pSelf->msgqRsp, pRcvMsg, ...); //接收指定key的消息if(ret > 0)return true; // 等待到对应的回应,返回成功}步骤S203:将收到的响应消息中的数据拷贝到接收缓存,并向返回成功的结果;步骤S204:根据消息类型对响应数据进行相应的处理,完成一次同步调用。
本步骤实施例为:将收到的响应消息中的数据拷贝到调用者传入的接收缓冲,并向调用者返回成功的结果。在调用msgrcv(pSelf->msgqRsp, pRcvMsg, ...)时,已经将数据拷贝到了调用者传入的接收消息缓冲,所以,当返回成功时,pRcvMsg携带的将是有效的响应消息数据,调用者可根据实际逻辑进行处理,一次同步调用完成。
所述完成一次同步调用包括:将完成一次同步调用过程封装到一个接口函数中,供模块调用。对于调用者来说,一次调用虽然横跨了本客户端模块的进程、服务器端进程、目标模块进程,并经历了消息的路由转发,响应等待等一系列复杂的处理过程,然而这些过程全部封装在本系统中,与调用者无关,对于调用者来说,调用本系统提供的同步调用接口函数后即获得了来自目标模块的响应数据。
所述完成一次同步调用包括:将完成一次同步调用过程中发送请求和接收响应接口函数提供给模块分别调用,实现模块间的异步调用;所述接收目标模块的响应消息,包括如下步骤:步骤S301:客户端B启动各个模块,调用初始化函数,创建客户端B模块的域套接字,并向所述服务器发起连接请求;本步骤实施例为:各个模块启动时,调用该申请所述系统的初始化函数,创建客户端模块的域套接字,并向服务器端发起连接请求:int ipcc_init_msg(int mid, char *mname, IPCC_MSG_CALL_BACK_FUNC pMsgFunc){// 省略部分预处理代码// 创建域套接字,并发起对服务器端的连接, 并保存本模块的信息pSelf->fd = uds_connect(IPC_DOMAN_SOCKET_NAME, SOCK_STREAM, mid, mname);if(IPC_ERROR == pSelf->fd) return IPC_ERROR;pSelf->state = CLIENT_STATE_CONNECTED;pSelf->mid = mid;pSelf->pMsgFunc = pMsgFunc; // 保存消息处理函数句柄if(mname){strncpy(pSelf->mname, mname, MOD_NAME_LEN);}// 创建域数据接收处理线程ret = pthread_create (&thread_id, NULL, ipcc_msg_rcv_thread, NULL);if(IPC_ERROR == ret) return IPC_ERROR;// 创建消息处理线程,用于接收到完整的消息后调用传入的消息处理句柄if(NULL != pMsgFunc){ret = pthread_create (&thread_id, NULL, ipcc_msg_proc_thread, NULL);if(IPC_ERROR == ret) return IPC_ERROR;}return ret;}步骤S302:同步接收服务器发送的消息,并根据消息类型分发到对应的消息队列;本步骤实施例为:同步读取域套接字,并检测读取到的数据,包括长度、消息标识魔鬼字等;然后根据消息的类型,将消息发送到对应的消息队列;while (CLIENT_STATE_STOP != pSelf->state) {// 循环等待接收消息memset(&pSelf->buff, 0, sizeof(pSelf->buff));len = uds_read(pSelf->fd, &pSelf->buff); //接收域套接字收到的数据while(len> 0){// 循环处理接收缓冲中的多条消息len = uds_check_msg(&pSelf->buff); // 检查消息完整性if(len> 0){pHeader = (IPC_MSG_HEADER_ST *)(pSelf->buff.buff);switch(pHeader->ipcMsg){ // 根据消息类型分别处理case PROTO_RESPONSE:{ // 响应类消息处理msgsnd(pSelf->msgqRsp,…, IPC_NOWAIT); // 发送到响应消息队列break;case PROTO_REQUEST: // 请求类消息处理msgsnd(pSelf->msgqNormal,.., IPC_NOWAIT); //发送到请求消息队列break;}default:break;}uds_buff_clean(&pSelf->buff, len);//清除处理完的消息}}}步骤S303:循环接收服务器发送的消息并分发到对应的消息队列,在接收到服务器发送的消息后调用所述初始化函数处理消息,并发送响应消息到所述服务器。
步骤304:所述调用初始化函数,创建客户端B模块的域套接字,包括:各个模块调用初始化函数时,同步传入模块的ID号、模块名称和模块的消息处理函数句柄;所述模块ID和模块名称将用于告知服务器发起连接请求的身份,消息处理函数句柄用于接收到消息后,调用所述函数句柄完成消息的处理。而这个处理过程完全有模块实现,实现了目标模块和本系统之间的解耦;本步骤实施例为:消息调度处理线程循环接收请求消息队列,在收到请求消息后,调用初始化时所传递进来的消息处理函数句柄进行处理:while (pSelf->state) {// 循环接收请求消息队列len = msgrcv(pSelf->msgqNormal, &rcvMsg, SIZEOF_MSG_LEN(IPC_MSG_ST), 0, MSG_NOERROR);if(len> 0){pSelf->rspTci = rcvMsg.header.tci; // 保持消息的会话id,用于发送对应的响应消息if(NULL != pSelf->pMsgFunc){ // 如果模块传入的消息处理回调函数句柄有效,则调用该函数pSelf->pMsgFunc(rcvMsg.header.userMsg, rcvMsg.header.src, rcvMsg.header.data,rcvMsg.header.dataLen);}}所述向所述服务器发起连接请求,包括:当模块发起连接请求时,通过域套接字的sun_path字段,携带模块ID和模块名称信息,为首次连接获知模块ID,并通过模块ID索引创造条件,并为鉴权提供信息;如果不采用这种方式,连接请求时,势必创建一个临时的实例以接受连接请求,并在完成连接后,需要通过一系列的消息交互,才能完成相关信息的传递,然后再将临时实例迁移到目标实例上,这样系统的复杂度大幅度提高,效率和可靠性大幅降低。
所述同步接收服务器发送的消息包括:同步读取接收服务器发送的消息的域套接字,并检测读取到数据的长度、消息标识魔鬼字;根据消息的类型,将消息发送到对应的消息队列;对于响应类消息,则发送到响应消息队列,由本模块的发送请求后正在等待响应的函数接收并处理;对于请求类消息,则发送到请求消息队列,由消息调度处理线程调度处理。
消息调度处理线程循环接收请求消息队列,在收到请求消息后,调用初始化时所传递进来的消息处理函数句柄进行处理,这样实现了本系统和目标模块间的分工合作。消息处理函数有模块外部实现,与本系统无关,但在消息处理完成后,需要向消息请求模块发出回应消息,以实现模块间调用的闭环。
所述客户端A与客户端B为系统的同一个客户端,客户端A与客户端B视为为同一个客户端的不同模块。
第二方面,本申请提出了一种基于域套接字实现模块间同步和异步调用的系统,如图2所示,包括:第一模块、第二模块、第三模块、第四模块;所述第一模块用于服务器创建域套接字并侦听连接请求;所述第二模块用于当侦听到客户端模块的连接请求时,服务器接受连接,并对所属模块进行鉴别,鉴别通过后并进入消息转发状态;所述第三模块用于异步接收客户端A请求消息,通过客户端A请求消息中包含的目标模块实例的域套接字,将消息发送到目标模块,实现消息的路由转发;所述第四模块用于接收目标模块的响应消息,并将所述响应消息发送到客户端A,完成一次同步调用。
所述第三模块包括:第一单元、第二单元、第三单元、第四单元;所述第一单元用于当客户端A模块需要同步调用另外客户端B一个模块的某个功能时,则向服务器发送请求消息;所述第二单元用于进入一个循环等待响应的过程,若等待超时则返回超时错误;若收到客户端B目标模块的响应消息则进入下一步处理;所述第三单元用于将收到的响应消息中的数据拷贝到接收缓存,并向返回成功的结果;所述第四单元用于根据消息类型对响应数据进行相应的处理,完成一次同步调用。
所述第四模块,包括:第五单元、第六单元、第七单元;所述第五单元用于客户端B启动各个模块,调用初始化函数,创建客户端B模块的域套接字,并向所述服务器发起连接请求;所述第六单元用于同步接收服务器发送的消息,并根据消息类型分发到对应的消息队列;所述第七单元用于循环接收服务器发送的消息并分发到对应的消息队列,在接收到服务器发送的消息后调用所述初始化函数处理消息,并发送响应消息到所述服务器。
本发明申请人结合说明书附图对本发明的实施示例做了详细的说明与描述,但是本领域技术人员应该理解,以上实施示例仅为本发明的优选实施方案,详尽的说明只是为了帮助读者更好地理解本发明精神,而并非对本发明保护范围的限制,相反,任何基于本发明的发明精神所作的任何改进或修饰都应当落在本发明的保护范围之内。
Claims (10)
1.一种基于域套接字实现模块间同步和异步调用的方法,其特征在于,包括如下步骤:
服务器创建域套接字并侦听连接请求;
当侦听到客户端模块的连接请求时,服务器接受连接,并对所属模块进行鉴别,鉴别通过后并进入消息转发状态;
异步接收客户端A请求消息,通过客户端A请求消息中包含的目标模块实例的域套接字,将消息发送到目标模块,实现消息的路由转发;
接收目标模块的响应消息,并将所述响应消息发送到客户端A,完成一次同步调用。
2.如权利要求1所述的基于域套接字实现模块间同步和异步调用的方法,其特征在于,所述服务器创建域套接字并侦听连接请求,包括如下步骤:
服务器启动服务进程;
根据系统中的模块编号和数量,初始化对应的模块实例单元;
创建服务器中用于侦听的域套接字;
进入循环侦听模式,等待各个模块的连接请求。
3.如权利要求1所述的基于域套接字实现模块间同步和异步调用的方法,其特征在于,所述当侦听到客户端模块的连接请求时,服务器接受连接,并对所属模块进行鉴别,鉴别通过后并进入消息转发状态,包括如下步骤:
所述当侦听到一个模块的连接请求时,创建一个域套接字,设置为异步模式,并用所述套接字接受来自模块的连接请求;
在域套接字连接请求的附属信息中,包括发起连接请求模块的模块ID和模块名称;
通过所述模块ID和模块名称进行鉴别;
当鉴别通过后,将通过模块ID直接索引到模块实例,并将所述模块实例转为消息转发状态;
对所属模块进行鉴别,鉴别通过后并进入消息转发状态。
4.如权利要求1所述的基于域套接字实现模块间同步和异步调用的方法,其特征在于,所述异步接收客户端A请求消息,通过客户端A请求消息中包含的目标模块实例的域套接字,将消息发送到目标模块,实现消息的路由转发,包括:
异步接收客户端请求消息;
对接收到的请求消息进行长度判断,若接收数据达到消息头部长度,则长度检查通过;
若检测消息头部中数据是消息头部的魔鬼字,则读取消息长度信息,并根据所述长度信息判断是否接收到完整的消息数据,若消息数据完整,则检查完整性通过;
若通过长度检查以及完整性检查时,则表明所述消息为正确且完整;若没有通过长度检查或完整性检查其中一项或两项时,则表明所述消息为不正确的;
将所述消息提交给消息路由转发函数进行处理;
消息路由转发函数根据消息的目标模块ID,直接索引到目标模块实例,并通过目标模块实例中的域套接字将消息发送出去,实现消息的路由转发过程;
在消息转发完成后,将所述消息长度信息从缓冲区清除,并继续判断是否有下一条消息直到处理完缓冲区内所有的消息。
5.如权利要求1所述的基于域套接字实现模块间同步和异步调用的方法,其特征在于,所述异步接收客户端A请求消息包括:
当客户端A模块需要同步调用另外客户端B一个模块的某个功能时,则向服务器发送请求消息;
进入一个循环等待响应的过程,若等待超时则返回超时错误;若收到客户端B目标模块的响应消息则进入下一步处理;
将收到的响应消息中的数据拷贝到接收缓存,并向返回成功的结果;
根据消息类型对响应数据进行相应的处理,完成一次同步调用。
6.如权利要求1所述的基于域套接字实现模块间同步和异步调用的方法,其特征在于,所述接收目标模块的响应消息,包括如下步骤:
客户端B启动各个模块,调用初始化函数,创建客户端B模块的域套接字,并向所述服务器发起连接请求;
同步接收服务器发送的消息,并根据消息类型分发到对应的消息队列;
循环接收服务器发送的消息并分发到对应的消息队列,在接收到服务器发送的消息后调用所述初始化函数处理消息,并发送响应消息到所述服务器。
7.如权利要求6所述的基于域套接字实现模块间同步和异步调用的方法,其特征在于,所述调用初始化函数,创建客户端B模块的域套接字,包括:各个模块调用初始化函数时,同步传入模块的ID号、模块名称和模块的消息处理函数句柄;所述模块ID和模块名称将用于告知服务器发起连接请求的身份,消息处理函数句柄用于接收到消息后,调用所述函数句柄完成消息的处理。
8.如权利要求6所述的基于域套接字实现模块间同步和异步调用的方法,其特征在于,所述同步接收服务器发送的消息包括:
同步读取接收服务器发送的消息的域套接字,并检测读取到数据的长度、消息标识魔鬼字;
根据消息的类型,将消息发送到对应的消息队列;
对于响应类消息,则发送到响应消息队列,由本模块的发送请求后正在等待响应的函数接收并处理;对于请求类消息,则发送到请求消息队列,由消息调度处理线程调度处理。
9.如权利要求6所述的基于域套接字实现模块间同步和异步调用的方法,其特征在于,所述客户端A与客户端B为系统的同一个客户端,客户端A与客户端B视为为同一个客户端的不同模块。
10.一种基于域套接字实现模块间同步和异步调用的系统,其特征在于,包括:
第一模块、第二模块、第三模块、第四模块;
所述第一模块用于服务器创建域套接字并侦听连接请求;
所述第二模块用于当侦听到客户端模块的连接请求时,服务器接受连接,并对所属模块进行鉴别,鉴别通过后并进入消息转发状态;
所述第三模块用于异步接收客户端A请求消息,通过客户端A请求消息中包含的目标模块实例的域套接字,将消息发送到目标模块,实现消息的路由转发;
所述第四模块用于接收目标模块的响应消息,并将所述响应消息发送到客户端A,完成一次同步调用。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202210847825.1A CN114979233A (zh) | 2022-07-19 | 2022-07-19 | 基于域套接字实现模块间同步和异步调用的方法和系统 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202210847825.1A CN114979233A (zh) | 2022-07-19 | 2022-07-19 | 基于域套接字实现模块间同步和异步调用的方法和系统 |
Publications (1)
Publication Number | Publication Date |
---|---|
CN114979233A true CN114979233A (zh) | 2022-08-30 |
Family
ID=82969804
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN202210847825.1A Pending CN114979233A (zh) | 2022-07-19 | 2022-07-19 | 基于域套接字实现模块间同步和异步调用的方法和系统 |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN114979233A (zh) |
Cited By (1)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN115640153A (zh) * | 2022-12-22 | 2023-01-24 | 北京智联安科技有限公司 | 系统架构、消息处理方法、装置、电子设备及存储介质 |
Citations (15)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN101206590A (zh) * | 2006-12-21 | 2008-06-25 | 国际商业机器公司 | 用于扩展用于通信的Unix域套接字的方法、装置和系统 |
CN102469064A (zh) * | 2010-11-03 | 2012-05-23 | 中兴通讯股份有限公司 | 通信实现方法及通信设备 |
CN104426800A (zh) * | 2013-08-22 | 2015-03-18 | 塔塔顾问服务有限公司 | 用于在对等通信网络中管理消息队列的系统和方法 |
CN104503853A (zh) * | 2014-12-25 | 2015-04-08 | 般固(北京)科技股份有限公司 | 一种Linux系统上的多进程服务器程序的会话保持方法 |
CN106648928A (zh) * | 2016-11-29 | 2017-05-10 | 成都广达新网科技股份有限公司 | 一种进程间通讯的方法及装置 |
CN106878473A (zh) * | 2017-04-20 | 2017-06-20 | 腾讯科技(深圳)有限公司 | 一种消息处理方法、服务器集群及系统 |
CN109347951A (zh) * | 2018-10-17 | 2019-02-15 | 平安普惠企业管理有限公司 | 文件导出方法、装置、计算机设备及计算机可读存储介质 |
CN109547162A (zh) * | 2018-12-06 | 2019-03-29 | 普康迪(北京)数码科技股份有限公司 | 基于两套单向边界的数据通信方法 |
CN109922059A (zh) * | 2019-02-28 | 2019-06-21 | 南京科谷智能科技有限公司 | 基于套接字的客户端与服务端保持连接的方法 |
US20190327332A1 (en) * | 2018-04-24 | 2019-10-24 | NGINX, Inc. | Passing Listener Sockets Between Web Server Processes |
CN110958143A (zh) * | 2019-11-26 | 2020-04-03 | 浙江大学 | 一种多线程跨层式信息处理平台架构及信息处理方法 |
CN112130932A (zh) * | 2020-09-29 | 2020-12-25 | 珠海海鸟科技有限公司 | 一种单实例运行的方法、装置及电子设备 |
CN113645294A (zh) * | 2021-08-06 | 2021-11-12 | 腾讯科技(深圳)有限公司 | 消息获取方法、装置、计算机设备和消息传输系统 |
US20220050723A1 (en) * | 2019-11-01 | 2022-02-17 | Sap Portals Israel Ltd. | Lightweight remote process execution |
CN114661492A (zh) * | 2022-03-03 | 2022-06-24 | 深圳融安网络科技有限公司 | 进程通信方法、系统、终端设备及介质 |
-
2022
- 2022-07-19 CN CN202210847825.1A patent/CN114979233A/zh active Pending
Patent Citations (15)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN101206590A (zh) * | 2006-12-21 | 2008-06-25 | 国际商业机器公司 | 用于扩展用于通信的Unix域套接字的方法、装置和系统 |
CN102469064A (zh) * | 2010-11-03 | 2012-05-23 | 中兴通讯股份有限公司 | 通信实现方法及通信设备 |
CN104426800A (zh) * | 2013-08-22 | 2015-03-18 | 塔塔顾问服务有限公司 | 用于在对等通信网络中管理消息队列的系统和方法 |
CN104503853A (zh) * | 2014-12-25 | 2015-04-08 | 般固(北京)科技股份有限公司 | 一种Linux系统上的多进程服务器程序的会话保持方法 |
CN106648928A (zh) * | 2016-11-29 | 2017-05-10 | 成都广达新网科技股份有限公司 | 一种进程间通讯的方法及装置 |
CN106878473A (zh) * | 2017-04-20 | 2017-06-20 | 腾讯科技(深圳)有限公司 | 一种消息处理方法、服务器集群及系统 |
US20190327332A1 (en) * | 2018-04-24 | 2019-10-24 | NGINX, Inc. | Passing Listener Sockets Between Web Server Processes |
CN109347951A (zh) * | 2018-10-17 | 2019-02-15 | 平安普惠企业管理有限公司 | 文件导出方法、装置、计算机设备及计算机可读存储介质 |
CN109547162A (zh) * | 2018-12-06 | 2019-03-29 | 普康迪(北京)数码科技股份有限公司 | 基于两套单向边界的数据通信方法 |
CN109922059A (zh) * | 2019-02-28 | 2019-06-21 | 南京科谷智能科技有限公司 | 基于套接字的客户端与服务端保持连接的方法 |
US20220050723A1 (en) * | 2019-11-01 | 2022-02-17 | Sap Portals Israel Ltd. | Lightweight remote process execution |
CN110958143A (zh) * | 2019-11-26 | 2020-04-03 | 浙江大学 | 一种多线程跨层式信息处理平台架构及信息处理方法 |
CN112130932A (zh) * | 2020-09-29 | 2020-12-25 | 珠海海鸟科技有限公司 | 一种单实例运行的方法、装置及电子设备 |
CN113645294A (zh) * | 2021-08-06 | 2021-11-12 | 腾讯科技(深圳)有限公司 | 消息获取方法、装置、计算机设备和消息传输系统 |
CN114661492A (zh) * | 2022-03-03 | 2022-06-24 | 深圳融安网络科技有限公司 | 进程通信方法、系统、终端设备及介质 |
Non-Patent Citations (4)
Title |
---|
ACUITY: "【Linux应用编程】基于UNIX域套接字的进程间通信", 《HTTPS://BLOG.CSDN.NET/QQ_20553613/ARTICLE/DETAILS/107497884》 * |
何小平等: "基于Unix域Socket的父子进程间心跳机制的实现", 《福建电脑 应用与开发》 * |
李文杰等: "基于消息队列机制的应用服务系统的设计", 《计算机系统应用》 * |
陈莉君等: "Android进程间通信Binder扩展模型的设计与实现", 《西安邮电大学学报》 * |
Cited By (1)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN115640153A (zh) * | 2022-12-22 | 2023-01-24 | 北京智联安科技有限公司 | 系统架构、消息处理方法、装置、电子设备及存储介质 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
US20040068479A1 (en) | Exploiting asynchronous access to database operations | |
US9479400B2 (en) | Servlet API and method for XMPP protocol | |
US7080120B2 (en) | System and method for collaborative processing of distributed applications | |
US6868442B1 (en) | Methods and apparatus for processing administrative requests of a distributed network application executing in a clustered computing environment | |
EP0956687B1 (en) | Web request broker controlling multiple processes | |
Chen et al. | Constructing adaptive software in distributed systems | |
US5748897A (en) | Apparatus and method for operating an aggregation of server computers using a dual-role proxy server computer | |
US6351772B1 (en) | Multiplexing of clients and applications among multiple servers | |
JP3853593B2 (ja) | ウェブアプリケーションサーバにおいて拡張可能な認証機構を実現するための方法および装置 | |
EP0767563B1 (en) | Method and apparatus for multiprotocol operation in a client/server system | |
US6584491B1 (en) | Arrangement for monitoring a progress of a message flowing through a distributed multiprocess system | |
EP0817445A2 (en) | Apparatus and method for indentifying server computer aggregation topologies | |
Correia et al. | Low complexity Byzantine-resilient consensus | |
CN108063813B (zh) | 一种集群环境下密码服务网络并行化的方法与系统 | |
CN114979233A (zh) | 基于域套接字实现模块间同步和异步调用的方法和系统 | |
CN111212117A (zh) | 一种远程交互的方法和装置 | |
CN114371935A (zh) | 网关处理方法、网关、设备及介质 | |
US20030202522A1 (en) | System for concurrent distributed processing in multiple finite state machines | |
CN115361348B (zh) | 由数据采集设备执行的与web浏览器通信的方法 | |
JP2001209621A (ja) | 「モバイル・ソフトウェア・エージェント」を経由してモバイル・データ処理装置と通信するシステムおよび方法 | |
US11489925B2 (en) | Information interaction methods, apparatuses, devices, and systems and storage media | |
CN115914330B (zh) | 一种基于nio异步线程模型的异构应用间通信方法 | |
Tangxiao et al. | Data transmission scheme based on publish/subscribe in workshop | |
CN115277647A (zh) | 实时会话消息的处理方法及装置、存储介质、终端 | |
Besnard et al. | Enabling Global MPI Process Addressing in MPI Applications |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
PB01 | Publication | ||
PB01 | Publication | ||
SE01 | Entry into force of request for substantive examination | ||
SE01 | Entry into force of request for substantive examination | ||
RJ01 | Rejection of invention patent application after publication |
Application publication date: 20220830 |
|
RJ01 | Rejection of invention patent application after publication |