分享
 
 
 

CORBA中的异步传输机制

王朝other·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

CORBA中的异步传输机制

(本文转载自软件工程专家网www.21cmm.com

于国良

本文主要讨论了的CORBA的异步传输机制ONEWAY以及事件服务。同时给出用DELPHIL利用ONEWAY以及事件服务异步传输机制实现的简单模型。

我们通常讨论的CORBA模型往往从客户机激发远程方法的角度来讨论C O R B A系统。象通常的客户机和服务器模型:客户机和服务器组件分别运行在不同的机器上,客户机发出一个请求,然后客户机阻塞。服务器主动监听从客户机来的请求。当收到一个请求后,服务器处理这个请求,并把结果返回给发出请求的客户机。客户机在等待回应时是阻塞的,只有在它接收到回答后才能继续处理。

在很多场合中,这种模型正好是用户所希望的。而且这种模型也符合传统的C/S模型,有问有答。但是在很多场合中并不需要这种模型,象股票系统中,普通股民眼中的价格更新,SCADA电力系统中的现场数据的显示等,都是不需要客户机发出请求,服务器就把结果返回给客户。还有在很多场合中,客户机发出一个请求后,并不希望得到服务器的回答,它需要的只是给服务器一个通知,象SCADA电力系统中的前置机往服务器上发数据,前置机并不需要等待这个服务器上的回答返回。为解决上述问题,CORBA提出了ONEWAY以及事件服务异步传输机制。

ONEWAY异步传输,顾名思义,ONEWAY就是"单向",即客户机发出它们的激发,然后继续处理,而用不着在发出一请求后阻塞,直到结果返回,当服务器完成对该请求的处理后,它可以通过向客户机发回一相应的单向激发把结?quot;返回",也可以不返回结果。

利用ONEWAY异步传输比较简单,它的一般步骤与普通CORBA应用一样:

1. 首先定义接口的IDL文件。

2. 编译IDL文件。

3. 编写服务器端程序。

4. 编写客户端程序。

这里我以DELPHI6(在DELPHI6中CORBA规范是由VisiBroker产品来实现的)为开发工具,来实现ONEWAY异步传输:

1. 首先定义接口的IDL文件:为了简单,我这里只定义了一个ONEWAY的方法。

module Pro

{

interface IOnewDemo;

interface IOnewDemo

{

oneway void onewaya(in long aa);

};

interface OnewDemoFactory

{

IOnewDemo CreateInstance(in string InstanceName);

};

};

2.和3在DELPHI6中,第二步和第三步是和在一起的。

选FILE-NEW-OTHER-CORBA-CORBA Server Application 在出现的IDL2Pas Create Server Dialog中按Add按钮加入刚才定义的IDL文件,按OK按钮以后,由IDL2Pas编译器来对它进行编译,生成Pro_c.pas,Pro-i.Pas,Pro_Impl.pas,Pro_s.pas四个文件,在Pro_Impl.pas文件中定义

procedure TIOnewDemo.onewaya ( const aa : Integer);

begin

form1.ListBox1.Items.Clear;

form1.ListBox1.Items.Add(inttostr(aa));

end;

在程序启动时进行初始化

procedure TForm1.FormCreate(Sender: TObject);

var

Acct: IOnewDemo;

begin

CorbaInitialize;

// Add CORBA server code here like this

Acct := TIOnewDemoSkeleton.Create('ygl', TIOnewDemo.Create);

BOA.ObjIsReady(Acct as _Object);

end;

编译生成服务器端程序。

4. 编写客户端程序:

在程序启动时进行初始化

procedure TForm1.FormCreate(Sender: TObject);

var

Acct: IOnewDemo;

begin

CorbaInitialize;

// Bind to the Corba server like this

Acct := TIOnewDemoHelper.bind;

end;

调用接口定义方法

procedure TForm1.Timer1Timer(Sender: TObject);//utilize the mothod of interface

var

i:integer;

begin

randomize;

i:=random(20);

acct.onewaya(i);

end;

编译生成客户器端程序。

CORBA中的事件服务是基于以下的原因定义的:

事件发送者和事件接收者的关系是松偶合的:事件发送者发送消息时,并不关心谁会收到消息。事件接收者接收消息时,也并不关心谁发送的消息。这里事件发送者称为事件供应者,事件接收者称为事件消费者。

在VisiBroker的事件实现中,它定义了两种事件模型:PUSH模型和PULL模型:如果一个事件是由供应者主动发出,消费者被动接收,就称为PUSH模型,如果一个事件是由消费者主动索取,供应者被动提供,就称为PULL模型。

PUSH模型可以简单表示为:

DELPHI6中在COSEVENT单元中定义了通用的接口:

PushConsumer , PushSupplier, PullSupplier , PullConsumer, ProxyPushConsumer

ProxyPullSupplier , ProxyPullConsumer , ProxyPushSupplier , ConsumerAdmin , SupplierAdmin , EventChannel…..

这里我用PUSH模型简单说一下通讯建立的过程:

供应者端:

1. 供应者获得一个SupplierAdmin对象。供应者通过调用Event_Channel的for_suppliers得到一个SupplierAdmin对象。

2. 供应者获得一个ProxyPushConsumer对象。供应者通过调用SupplierAdmin的obtain_push_consumer得到一个ProxyPushConsumer对象。

3. 供应者利用ProxyPushConsumer对象的connect_push_supplier连接远方的ProxyPushSupplier对象。

消费者端:

1. 消费者获得一个ConsumerAdmin对象。消费者通过调用Event_Channel的for_consumers得到一个ConsumerAdmin对象。

2. 消费者获得一个ProxyPushSupplier对象。消费者通过调用ConsumerAdmin的obtain_push_supplier得到一个ProxyPushSupplier对象。

3. 消费者利用ProxyPushSupplier对象的connect_push_consumer连接远方的ProxyPushConsumer对象。

在DELPHI6中对事件服务的PUSH模型实现的例子如下:

供应者端:

实现TpushSupplier类

TPushSupplier = class(TInterfacedObject, PushSupplier)

public

constructor Create;

procedure disconnect_push_supplier;

end;

主程序:

procedure TForm1.FormCreate(Sender: TObject);

var

PushSupplier_Skeleton,PushSupplier_Skeletonaaa : PushSupplier;

Event_Channel,Event_Channelaaa : EventChannel;

Supplier_Admin,Supplier_Adminaaa : SupplierAdmin;

Push_Consumer,Push_Consumeraaa : ProxyPushConsumer;

myAny:any;

begin

CorbaInitialize;

// Create the skeleton and register it with the boa

PushSupplier_Skeleton:=TPushSupplierSkeleton.Create('ygl', TPushSupplier.Create);

BOA.SetScope( RegistrationScope(1) );

BOA.ObjIsReady(PushSupplier_Skeleton as _Object);

//bind to the event channel and get a Supplier Admin object

获得事件信道接口,bind的参数是下面命令行中的参数ygl:

Event_Channel := TEventChannelHelper.bind('ygl');

//可以连接另一个事件信道bind的参数是另一个实例中的参数yglaaa:

// Event_Channelaaa := TEventChannelHelper.bind('yglaaa');

获得SupplierAdmin接口:

Supplier_Admin := Event_Channel.for_suppliers;

//get a push consumer and register the supplier object

获得ProxyPushConsumer接口:

Push_Consumer := Supplier_Admin.obtain_push_consumer;

连接ProxyPushSupplier接口

Push_Consumer.connect_push_supplier(PushSupplier_Skeleton);

往信道中推数据

randomize;

myany:= random(1000);

try

Push_Consumer.Push(myAny);

except

on EDisconnected do ShowMessage('Client Disconnected');

end;

end;

消费者端:

实现TPushConsumer类

TPushConsumer = class(TInterfacedObject, PushConsumer)

public

constructor Create;

procedure push(const data : Any);

procedure disconnect_push_consumer;

end;

这里,重要的方法是:

procedure TPushConsumer.push(const data : Any);

var

num :integer

begin

num := data;

Form1.ListBox1.Items.Add(IntToStr(num));

end;

它表示消费者收到数据后的处理。

主程序:

procedure TForm1.FormCreate(Sender: TObject);

var

PushConsumer_Skeleton : PushConsumer;

Event_Channel : EventChannel;

Consumer_Admin : ConsumerAdmin;

Push_Supplier : ProxyPushSupplier;

begin

CorbaInitialize;

// Create the skeleton and register it with the boa

PushConsumer_Skeleton:=TPushConsumerSkeleton.Create('ygl', TPushConsumer.Create);

BOA.SetScope( RegistrationScope(1) );

BOA.ObjIsReady(PushConsumer_Skeleton as _Object);

获得事件信道接口:

//bind to the event channel and get a Supplier Admin object

Event_Channel := TEventChannelHelper.bind('ygl');

获得ConsumerAdmin接口:

Consumer_Admin := Event_Channel.for_consumers;

//get a push consumer and register the supplier object

获得ProxyPushSupplier;接口:

Push_Supplier := Consumer_Admin.obtain_push_supplier;

连接ProxyPushConsumer接口

Push_Supplier.connect_push_consumer(PushConsumer_Skeleton);

end;

程序运行:

首先运行SmartAgent,再在…\VisiBroker\bin下以命令行方式运行channel ygl 然后分别运行供应者端,消费者端程序。

在这里要注意两个方面的问题:

1.由于大多数O R B使用T C P作为它们底层的传输,而T C P是一可靠的协议,所以即使用户认为是非阻塞的调用,实际上在T C P层还是阻塞的调用。用户的客户机应用程序可能不等待服务器应用程序接收并开始处理请求,但是客户机的T C P / I P栈却要等待,直到请求缓冲区被服务器的T C P / I P栈成功接收(和确认)。

2. 在Visibroker中并没有提供事件粒度的控制-过滤功能。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有