用Delphi建立通讯与数据交换服务器—Transceiver…

2008-02-23 07:17:43来源:互联网 阅读 ()

新老客户大回馈,云服务器低至5折

二、 Transceiver Service详解
1.Transceiver Service分析概要
Transceiver Service是Transceiver系统的核心构成,Transceiver Kernel负责从系统配置库读取Transceiver Console设定的Port、Channel定义与参数,运行时动态创建和管控通讯Port及其关联关系,对数据的收、发、缓冲进行调度、对日志、队列进行管理等。Transceiver Shell则是所支持全部类型的用于数据收发的Port的实现。
2.Transceiver Service设计概要
Transceiver Service是由Delphi中Service Application开发而成,Service Application可运行于系统态而非用户态,由操作系统Service Control Manager (SCM)负责程序的运行管理,Service没有用户界面,属于系统的后台程序。Transceiver Kernel是Transceiver类的一系列对Transceiver Shell建立和控管的方法,而Transceiver Shell则是一系列负责通讯的对象集合。
注:由于性能和负载的考虑,Transceiver Kernel只是从逻辑上实现上架构图中的功能划分,构成模块并未以完全对象化的方式实现。
3.Transceiver Service实现概要
i. 建立一个Service Application
从Delphi主菜单File中选择NEW|Other…在弹出的New Items对话框中选择NEW|Service Application ,可以看到生成的程序框架如下:
program Project1;
uses
SVCMgr,
Unit1 in 'Unit1.pas' {Service1: TService};
{$R *.RES}
begin
Application.Initialize;
Application.CreateForm(TService1, Service1);
Application.Run;
end.


unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, SvcMgr, Dialogs;
type
TService1 = class(TService)
private
{ Private declarations }
public
function GetServiceController: TServiceController; override;
{ Public declarations }
end;
var
Service1: TService1;
implementation
{$R *.DFM}
procedure ServiceController(CtrlCode: DWord); stdcall;
begin
Service1.Controller(CtrlCode);
end;
function TService1.GetServiceController: TServiceController;
begin
Result := ServiceController;
end;
end.
可以看到除了在uses单元引用了用于服务管理的SvcMgr、TService1继承自TServiced而非TForm及一个重载的GetServiceController函数和以stdcall方式调用的ServiceController过程之外,用Delphi建立一个服务程序并没有太多特别之处,Delphi Fans也许又要欢呼了,这就是Delphi RAD的强大迷人之处。另外,Service Application由于无法直接在运行时调试,也没有用户界面,开发时应考虑调试信息的无界面输出以利于调试排错。
ii. 创始满足特定需求的Port类
要使用运行处理机制统一的Transceiver Kernel,就要求Transceiver Shell中的Port有统一的处理规则,Shell中有些Port是Delphi开发环境中已有的组件类(如TCP、FTP等),而有些则不是(如MSMQ、File等)这时就需要自己动手建立一个可以满足需要的类。如:
type//由于没有用户界面,所以继承自TComponent而非TControl
TFilePort=class(TComponent)
private
FilePath:string;//获取或保存文件的文件夹位置
Prefix:string;//文件前缀
suffix:string;//文件后缀
end;
建立TFilePort类以后,Transceiver Kernel就可以使用统一的类处理方式引用和管理对象,达到从FilePath指定的文件夹下存取特定文件的目的。如果用于信源(Source),将从特定文件夹下获取满足条件的文件,如果用于信宿(Target),将把从相应信源(Source)得到的数据写入到指定文件中(事实上每一个Port对象的实际参数都来源于系统配置库中Port表的定义)。
另一个例子:
type
TCOMPort=class(TComponent)
private
ComFace:string;//获取或提交数据的COM接口
end;
TCOMPort将用于从指定COM组件接口中获取数据或将数据提交到指定的COM组件接口上进行后续处理。在Delphi中OleVariant类是实现COM组件调用的途径之一,使用TCOMPort类的必要性在于,Transceiver在必要的数据存取时才会将TCOMPort定义的COM接口实例化为OleVariant对象,使用结束即释放对象,这样能减少Transceiver和COM服务器的负载压力。其它类似组件也有相同考虑。作者此处的类举例只是一种模型,必要时应加入适当的方法与事件。在开发中作者实现的类有:TCOMPort、TMSMQPort、TDBPort、TFilePort等
iii. 多Channel的支持—声明Port的对象数组
Transceiver把一个通讯过程看作是源(Source)到目标(Target)的数据流过程,这样一个过程是Transceiver中的一个Channel,而这个Channel又是由至少两个Port构成的(一个用于Source,一个用于Target),所以要定义不定数量并且Source、Target自由组合的多个Channel,必须分别声明用于Source 和Target 的多种Port类的对象数组(并为他们建立对应的关联关系,稍后您将看到)。如:
private
{ Private declarations }
TCPSource:array of TServerSocket;// 用于TCP Source的对象数组
TCPTarget:array of TClientSocket;//用于TCP Target的对象数组
MailSource:array of TIdPOP3; //用于Mail Source的对象数组
MailTarget:array of TIdSMTP; //用于Mail Target的对象数组
fileSource:array of TFilePort; //用于File Source的对象数组
fileTarget:array of TFilePort; //用于File Target的对象数组
comSource:array of TCOMPort;//用于COM Source的对象数组
comTarget:array of TCOMPort; // 用于COM Target的对象数组
注:由于同一类型的用于Source和Target的Port运行规则的也完全不同,在Transceiver概念中被视为是完全不同并且无直接关系的对象。所以同一类型的Port,对象数组也按Source和Target分别建立。
iv. 运行时实例化对象数组
每一个对象数组的元素个数由Port Builder在运行时管理,如果用户通过Transceiver Console定义了一些某种类型的Port,Port Builder将按照其个数和各自参数实例化该对象数组。否则,该对象数组将不会被实例化。在Source类型的Port对象中,Name属性被设置为'Receive' Port ID 的形式,在之后的数据接收触发中,这将有助于Data Dispatcher定位对象和对不同类型的Port对象进行统一调度。Tag属性被用来向Channel Controller提供其所在Channel的target ID信息。

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:重新认识Delphi

下一篇:开发一个基于DCOM的局域网聊天室