亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

CORBA中的異步傳輸機制

系統(tǒng) 1856 0

CORBA中的異步傳輸機制

(本文轉(zhuǎn)載自軟件工程專家網(wǎng) www.21cmm.com

于國良

  本文主要討論了的CORBA的異步傳輸機制ONEWAY以及事件服務(wù)。同時給出用DELPHIL利用ONEWAY以及事件服務(wù)異步傳輸機制實現(xiàn)的簡單模型。

  我們通常討論的CORBA模型往往從客戶機激發(fā)遠程方法的角度來討論C O R B A系統(tǒng)。象通常的客戶機和服務(wù)器模型:客戶機和服務(wù)器組件分別運行在不同的機器上,客戶機發(fā)出一個請求,然后客戶機阻塞。服務(wù)器主動監(jiān)聽從客戶機來的請求。當收到一個請求后,服務(wù)器處理這個請求,并把結(jié)果返回給發(fā)出請求的客戶機。客戶機在等待回應(yīng)時是阻塞的,只有在它接收到回答后才能繼續(xù)處理。

  在很多場合中,這種模型正好是用戶所希望的。而且這種模型也符合傳統(tǒng)的C/S模型,有問有答。但是在很多場合中并不需要這種模型,象股票系統(tǒng)中,普通股民眼中的價格更新,SCADA電力系統(tǒng)中的現(xiàn)場數(shù)據(jù)的顯示等,都是不需要客戶機發(fā)出請求,服務(wù)器就把結(jié)果返回給客戶。還有在很多場合中,客戶機發(fā)出一個請求后,并不希望得到服務(wù)器的回答,它需要的只是給服務(wù)器一個通知,象SCADA電力系統(tǒng)中的前置機往服務(wù)器上發(fā)數(shù)據(jù),前置機并不需要等待這個服務(wù)器上的回答返回。為解決上述問題,CORBA提出了ONEWAY以及事件服務(wù)異步傳輸機制。

  ONEWAY異步傳輸,顧名思義,ONEWAY就是"單向",即客戶機發(fā)出它們的激發(fā),然后繼續(xù)處理,而用不著在發(fā)出一請求后阻塞,直到結(jié)果返回,當服務(wù)器完成對該請求的處理后,它可以通過向客戶機發(fā)回一相應(yīng)的單向激發(fā)把結(jié)?quot;返回",也可以不返回結(jié)果。

  利用ONEWAY異步傳輸比較簡單,它的一般步驟與普通CORBA應(yīng)用一樣:
  1. 首先定義接口的IDL文件。
  2. 編譯IDL文件。
  3. 編寫服務(wù)器端程序。
  4. 編寫客戶端程序。

  這里我以DELPHI6(在DELPHI6中CORBA規(guī)范是由VisiBroker產(chǎn)品來實現(xiàn)的)為開發(fā)工具,來實現(xiàn)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 在出現(xiàn)的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;

  編譯生成服務(wù)器端程序。

4. 編寫客戶端程序:

  在程序啟動時進行初始化
  procedure TForm1.FormCreate(Sender: TObject);
  var
  Acct: IOnewDemo;
  begin
  CorbaInitialize;
  // Bind to the Corba server like this
  Acct := TIOnewDemoHelper.bind;
  end;

  調(diào)用接口定義方法
  procedure TForm1.Timer1Timer(Sender: TObject);//utilize the mothod of interface
  var
  i:integer;
  begin
  randomize;
  i:=random(20);
  acct.onewaya(i);
  end;

  編譯生成客戶器端程序。

  CORBA中的事件服務(wù)是基于以下的原因定義的:

  事件發(fā)送者和事件接收者的關(guān)系是松偶合的:事件發(fā)送者發(fā)送消息時,并不關(guān)心誰會收到消息。事件接收者接收消息時,也并不關(guān)心誰發(fā)送的消息。這里事件發(fā)送者稱為事件供應(yīng)者,事件接收者稱為事件消費者。

  在VisiBroker的事件實現(xiàn)中,它定義了兩種事件模型:PUSH模型和PULL模型:如果一個事件是由供應(yīng)者主動發(fā)出,消費者被動接收,就稱為PUSH模型,如果一個事件是由消費者主動索取,供應(yīng)者被動提供,就稱為PULL模型。

  PUSH模型可以簡單表示為:


  DELPHI6中在COSEVENT單元中定義了通用的接口:

  PushConsumer , PushSupplier, PullSupplier , PullConsumer, ProxyPushConsumer
  ProxyPullSupplier , ProxyPullConsumer , ProxyPushSupplier , ConsumerAdmin , SupplierAdmin ,   EventChannel…..

  這里我用PUSH模型簡單說一下通訊建立的過程:

供應(yīng)者端:

  1. 供應(yīng)者獲得一個SupplierAdmin對象。供應(yīng)者通過調(diào)用Event_Channel的for_suppliers得到一個SupplierAdmin對象。

  2. 供應(yīng)者獲得一個ProxyPushConsumer對象。供應(yīng)者通過調(diào)用SupplierAdmin的obtain_push_consumer得到一個ProxyPushConsumer對象。

  3. 供應(yīng)者利用ProxyPushConsumer對象的connect_push_supplier連接遠方的ProxyPushSupplier對象。

消費者端:

  1. 消費者獲得一個ConsumerAdmin對象。消費者通過調(diào)用Event_Channel的for_consumers得到一個ConsumerAdmin對象。

  2. 消費者獲得一個ProxyPushSupplier對象。消費者通過調(diào)用ConsumerAdmin的obtain_push_supplier得到一個ProxyPushSupplier對象。

  3. 消費者利用ProxyPushSupplier對象的connect_push_consumer連接遠方的ProxyPushConsumer對象。
在DELPHI6中對事件服務(wù)的PUSH模型實現(xiàn)的例子如下:

供應(yīng)者端:

  實現(xiàn)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的參數(shù)是下面命令行中的參數(shù)ygl:
  Event_Channel := TEventChannelHelper.bind('ygl');
  //可以連接另一個事件信道bind的參數(shù)是另一個實例中的參數(shù)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);
  往信道中推數(shù)據(jù)
  randomize;
  myany:= random(1000);
  try
  Push_Consumer.Push(myAny);
  except
  on EDisconnected do ShowMessage('Client Disconnected');
  end;
  end;

消費者端:

  實現(xiàn)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;
  它表示消費者收到數(shù)據(jù)后的處理。

主程序:

  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 然后分別運行供應(yīng)者端,消費者端程序。

  在這里要注意兩個方面的問題:

  1.由于大多數(shù)O R B使用T C P作為它們底層的傳輸,而T C P是一可靠的協(xié)議,所以即使用戶認為是非阻塞的調(diào)用,實際上在T C P層還是阻塞的調(diào)用。用戶的客戶機應(yīng)用程序可能不等待服務(wù)器應(yīng)用程序接收并開始處理請求,但是客戶機的T C P / I P棧卻要等待,直到請求緩沖區(qū)被服務(wù)器的T C P / I P棧成功接收(和確認)。

  2. 在Visibroker中并沒有提供事件粒度的控制-過濾功能。



Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=2319


CORBA中的異步傳輸機制


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 激情四播| 成人欧美一区二区三区视频xxx | 日本天天操| 91精品久久国产青草 | 久久香蕉国产线看观看8青草 | 成人欧美一区二区三区黑人免费 | 伊人久久亚洲综合天堂 | 欧美一区二区三区在线视频 | 成人欧美一区二区三区在线观看 | 亚洲免费毛片 | 国产精品伦理久久久久 | 日本三级中文 | 国产亚洲一欧美一区二区三区 | 大色综合色综合资源站 | 欧美丰满大乳大屁股毛片 | 国产精品免费观看视频 | 高清黄色直接看 | 操操操综合网 | 一级毛片黄色片 | 宅男在线看片 | 欧美日韩久久中文字幕 | 91亚洲国产在人线播放午夜 | 羞羞网站在线看 | 成年女人在线观看片免费视频 | 五月天综合久久 | 91官网| 久草视频免费播放 | 一级毛片aa高清免费观看 | 奇米888影视 | 欧美韩国日本在线观看 | 国产亚洲精品热视频在线观看 | 亚洲精品国产成人7777 | 免费四虎永久在线精品 | 亚洲国产成人精品91久久久 | 99热久久国产精品这里有全部 | 手机在线一区二区三区 | 久久激情五月 | 亚洲日韩中文字幕在线播放 | 国产免费不卡视频 | 伦理久久 | 日日摸夜夜嗷嗷叫日日拍 |