1、软件系统之间的接口方式软件系统之间的接口方式之马矢奏春创作创作时间:二零二一年六月三十日 概述 软件接口是实现一个系统跟另外系统进行信息交互的桥梁,在分歧的系统之间,根据系统的关联水平的分歧存在紧耦合和松耦合两种:紧耦合要求接口响应反应快,消息不能阻塞;松耦合对响应反应要求比力低.在目前应用中, Socket 、消息队列(Message Queue)、 WebService等都有相应的应用,可是应用中发现各通讯方式有自己固有的特征,“适合的才是最好的”,这是真理. 在接口和系统信息交互的过程中,两种模式使用得很普遍:同法式用和异法式用,同法式用要求接口发出请求消息后必需等候服务端系统的应答消息
2、,接口阻塞直至超时;异法式用则发出请求消息后,接口可以从事其它处置,按时轮询服务端应答消息和消息或事件通知.同步方式简单,可是很容易造成接口阻塞,造成消息积压超时. 技术实现 Socket 通讯 Socket 通讯相对来说是很古老的通讯方式,也是最经常使用的通讯方式. Socket 通讯有阻塞和非阻塞两种方式.在同步方式,采纳阻塞编程比力简单,可是为了防止接口阻塞,我们需要设置 Socket 超时,因此可以使用 Socket 的 SELECT 模型(参考如下示例代码): ReceLen=0; CurReceLen=0; for(;) iResult=select(0,&fdread,NULL,
3、NULL,&timeout); if(iResult=0) AfxMessageBox(接收应答消息超时!,MB_OK|MB_ICONERROR); closesocket(Socket); return FALSE; CurReceLen = recv(Socket, oBuf+ReceLen, len, NO_FLAG_SET); if(CurReceLen0) & (CurReceLen != SOCKET_ERROR) oBufReceLen+CurReceLen=0; memcpy(char *)&MsgLen,oBuf,sizeof(WORD32); MsgLen=ntohl(Ms
4、gLen); if(ReceLen+CurReceLen=MsgLen) ReceLen+=CurReceLen; break; ReceLen+=CurReceLen; 在异步方式下,采纳非阻塞方式实现比力方便,在非阻塞方式下可使用WSAAsyncSelect模型和 WSAEventSelect 模型: WSAAsyncSelect模型基于消息, WSAEventSelect 模型基于事件,下面的示例代码设置了 Socket 进行读写和关闭把持的消息: status = WSAAsyncSelect(TempSocket, hWnd, WSA_READ, FD_READ | FD_CLOSE
5、 | FD_WRITE); if (status = SOCKET_ERROR) WriteLogFile(Set stream socket module fail!IP(%s),Port(%d) and error(%d),GetIPAddr(PeerMap+node)-IPAddr),(PeerMap+node)-PeerPortNo,WSAGetLastError(); CloseSocket(TempSocket,_LINE_,_FILE_); return FALSE; 无论使用阻塞方式或非阻塞方式编程,需要重点考虑的一个问题:粘包现象,即应用发送两个或以上的数据包,在 Socke
6、t 通讯层将数据包合并成一个发送出去,因此接收端收到数据包以后需要对数据包根据应用界说的长度进行拆分,否则招致应用层丢包.应用方式可以由用户封转成DLL供使用方使用.消息队列(Message Queue)利用 MSMQ(Microsoft Message Queue),应用法式开发人员可以通过发送和接收消息方便地与应用法式进行快速可靠的通信.消息处置为您提供了有保证的消息传递和执行许多业务处置的可靠的防故障方法. MSMQ与XML Web Services和.Net Remoting一样,是一种分布式开发技术.可是在使用XML Web Services或.Net Remoting组件时,Cli
7、ent端需要和Server端实时交换信息,Server需要坚持联机.MSMQ则可以在Server离线的情况下工作,将Message临时保管在Client真个消息队列中,以后联机时再发送到Server端处置. 显然,MSMQ不适合于Client需要Server端及时响应的这种情况,MSMQ以异步的方式和Server端交互,不用担忧等候Server真个长时间处置过程. 虽然XML Web Services和.Net Remoting都提供了OneWay属性来处置异法式用,用来解决Server端长方法调用长时间阻碍Client端.可是不能解决年夜量Client负载的问题,此时Server接受的请求快
8、于处置请求. 一般情况下,OneWay属性不用于专门的消息服务中. 1. 基本术语和概念( Basic terms and concepts ) “消息”是在两台计算机间传送的数据单元.消息可以非常简单,例如只包括文本字符串;也可以更复杂,可能包括嵌入对象. 消息被发送到队列中.“消息队列”是在消息的传输过程中保管消息的容器.消息队列管理器在将消息从它的源中继到它的目标时充任中间人.队列的主要目的是提供路由并保证消息的传递;如果发送消息时接收者不成用,消息队列会保管消息,直到可以胜利地传递它. “消息队列”是 Microsoft 的消息处置技术,它在任何装置了 Microsoft Window
9、s 的计算机组合中,为任何应用法式提供消息处置和消息队列功能,无论这些计算机是否在同一个网络上或者是否同时联机. “消息队列网络”是能够相互间来回发送消息的任何一组计算机.网络中的分歧计算机在确保消息顺利处置的过程中饰演分歧的角色.它们中有些提供路由信息以确定如何发送消息,有些保管整个网络的重要信息,而有些只是发送和接收消息. “消息队列”装置期间,管理员确定哪些服务器可以互相通信,并设置特定服务器的特殊角色.构成此“消息队列”网络的计算机称为“站点”,它们之间通过“站点链接”相互连接.每个站点链接都有一个关联的“开销”,它由管理员确定,指示了经过此站点链接传递消息的频率. “消息队列”管理员
10、还在网络中设置一台或多台作为“路由服务器”的计算机.路由服务器检查各站点链接的开销,确定经过多个站点传递消息的最快和最有效的方法,以此决定如何传递消息. 2. 队列类型( Queue Type ) 有两种主要的队列类型:由您或网络中的其他用户创立的队列和系统队列. 用户创立的队列可能是以下任何一种队列: “公共队列”在整个“消息队列”网络中复制,而且有可能由网络连接的所有站点访问. “专用队列”不在整个网络中发布.相反,它们仅在所驻留的本地计算机上可用.专用队列只能由知道队列的完整路径名或标签的应用法式访问. “管理队列”包括确认在给定“消息队列”网络中发送的消息回执的消息.指定希望Messa
11、geQueue 组件使用的管理队列(如果有的话). “响应队列”包括目标应用法式接收到消息时返回给发送应用法式的响应消息.指定希望 MessageQueue 组件使用的响应队列(如果有的话). 系统生成的队列一般分为以下几类: “日记队列”可选地存储发送消息的副本和从队列中移除的消息副本.每个“消息队列”客户端上的单个日记队列存储从该计算机发送的消息副本.在服务器上为每个队列创立了一个独自的日记队列.此日记跟踪从该队列中移除的消息. “死信队列”存储无法传递或已过期的消息的副本.如果过期或无法传递的消息是事务性消息,则被存储在一种特殊的死信队列中,称为“事务性死信队列”.死信存储在过期消息所在
12、的计算机上.有关超时期限和过期消息的更多信息,请拜会默认消息属性. “陈说队列”包括指示消息达到目标所经过的路由的消息,还可以包括测试消息.每台计算机上只能有一个陈说队列. “专用系统队列”是一系列存储系统执行消息处置把持所需的管理和通知消息的专用队列. 在应用法式中进行的年夜大都工作都涉及访问公共队列及其消息.可是,根据应用法式的日记记录、确认和其他特殊处置需要,在日常把持中很可能要使用几种分歧的系统队列. 3. 同步和异步通信( Synchronous VS. Asynchronous Communication ) 队列通信天生就是异步的,因为将消息发送到队列和从队列中接收消息是在分歧的
13、进程中完成的.另外,可以异步执行接收把持,因为要接收消息的人可以对任何给定的队列调用 BeginReceive 方法,然后立即继续其他任务而不用等候回答.这与人们所了解的“同步通信”截然分歧. 在同步通信中,请求的发送方在执行其他任务前,必需等候来自预定接收方的响应.发送方等候的时间完全取决于接收方处置请求和发送响应所用的时间. 4. 同消息队列交互( Interacting with Message Queues ) 消息处置和消息为基于服务器的应用法式组件之间的进程间通信提供了强年夜灵活的机制.同组件间的直接调用相比,它们具有若干优点,其中包括: 稳定性 组件失败抵消息的影响水平远远小于组
14、件间的直接调用,因为消息存储在队列中并一直留在那里,直到被适本地处置.消息处置同事务处置相似,因为消息处置是有保证的. 消息优先级 更紧急或更重要的消息可在相对不重要的消息之前接收,因此可以为关键的应用法式保证足够的响应时间. 脱机能力 发送消息时,它们可被发送光临时队列中并一直留在那里,直到被胜利地传递.当因任何原因对所需队列的访问不成用时,用户可以继续执行把持.同时,其他把持可以继续进行,如同消息已经获得了处置一样,这是因为网络连接恢复时消息传递是有保证的. 事务性消息处置 将多个相关消息耦合为单个事务,确保消息按顺序传递、只传递一次而且可以从它们的目标队列中被胜利地检索.如果呈现任何毛病
15、,将取消整个事务. 平安性 MessageQueue 组件基于的消息队列技术使用 Windows 平安来呵护访问控制,提供审核,并对组件发送和接收的消息进行加密和验证. 5. 在 .Net 环境下编写简单的 Message Queue 法式 (1)先装置Message Queuing Services 通过Control Panel,“Add/Remove Programs” “Add/Remove Windows Components”步伐装置MSMQ. MSMQ可以装置为工作组模式或域模式.如果装置法式没有找到一台运行提供目录服务的消息队列的服务器,则只可以装置为工作组模式,此计算机上的“
16、消息队列”只支持创立专用队列和创立与其他运行“消息队列”的计算机的直接连接. (2)配置MSMQ 翻开Computer Management Message Queuing,在Private Queues下创立MSMQDemo队列 (3)编写代码简单演示MSMQ对象 MessageQueue 类是“消息队列”周围的包装.MessageQueue 类提供对“消息队列”队列的引用.可以在 MessageQueue 构造函数中指定一个连接到现有资源的路径,或者可在服务器上创立新队列.在调用 Send、Peek 或 Receive 之前,必需将 MessageQueue 类的新实例与某个现有队列关联.
17、 MessageQueue 支持两种类型的消息检索:同步和异步.同步的 Peek 和 Receive 方法使进程线程用指定的间隔时间等候新消息达到队列.异步的 BeginPeek 和 BeginReceive 方法允许主应用法式任务在消息达到队列之前,在独自的线程中继续执行.这些方法通过使用回调对象和状态对象进行工作,以便在线程之间进行信息通讯. / Send Message private void btnSendMessage_Click(object sender, System.EventArgs e) / Open queue System.Messaging.MessageQueu
18、e queue = new System.Messaging.MessageQueue(.Private$MSMQDemo); / Create message System.Messaging.Message message = new System.Messaging.Message(); message.Body = txtMessage.Text.Trim(); message.Formatter = new System.Messaging.XmlMessageFormatter(new Type typeof(string); / Put message into queue qu
19、eue.Send(message); / Receive Message private void btnReceiveMessage_Click(object sender, System.EventArgs e) / Open queue System.Messaging.MessageQueue queue = new System.Messaging.MessageQueue(.Private$MSMQDemo); / Receive message, 同步的Receive方法阻塞以后执行线程,直到一个message可以获得 System.Messaging.Message messa
20、ge = queue.Receive(); message.Formatter = new System.Messaging.XmlMessageFormatter(new Type typeof(string); txtReceiveMessage.Text = message.Body.ToString(); Demo界面: WebServiceSOAP 作为一种协议,同服务端 WebService 进行通讯.微软提供了 SOAP 协议的 SDK ,我使用的是微软的 SOAP Toolkit3.0 ,这是基于 COM 的一套组件,因此具有 COM 的特征,在调用参数的处置, windows
21、 和 unix 顺序恰好相反,下面的代码实现了调用一个 Web Service : if(!m_bFlatType) for(i=paramNum,j=0;ij;i-,j+) VARIANTARG argTemp; VariantInit(&argTemp); argTemp=vai-1; vai-1=vaj; vaj=argTemp; params.cArgs = paramNum; params.rgvarg = va; params.cNamedArgs = 0; params.rgdispidNamedArgs = NULL; hr = SoapConnect.pSoapClienti
22、ndex-Invoke(dispidFn, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, ¶ms, &result, 0, 0); if(FAILED(hr) HandleHResult(_T(Invoke of +strService+ method failed.), hr); VariantClear(&result); for(i=0;iMAX_PARAM_NUM;i+) VariantClear(&vai); SysFreeString(bstrServiceName); CoUninitialize(); return FALSE; 总结 在三种通讯方式中,各有优缺点,可是主要还在于服务端采纳什么技术方案来实现,接口必需对应采纳相应的通讯模式. 创作时间:二零二一年六月三十日
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1