1. 程式人生 > >CORBA的簡單介紹及HelloWorld

CORBA的簡單介紹及HelloWorld

CORBA概述

CORBA(Common Object Request Broker Architecture,公共物件請求代理體系結構)是由OMG組織制訂的一種標準的面向物件應用程 序體系規範。或者說 CORBA體系結構是OMG為解決分散式處理環境(DCE)中,硬體和軟體系統的互連而提出的一種解決方案。

OMG:Object Management Group,物件管理組織。是一個國際化的、開放成員的、非盈利性的計算機行業標準協會,該協會成立於1989年,其職責是為應用開發提供一個公共框架,制訂工業指南和物件管理規範,加快物件技術的發展。。任何組織都可以加入OMG並且參與標準制定過程。OMG制定了統一建模語言UnifiedModeling Language™ (UML®),模型驅動架構Model Driven Architecture® (MDA®)等建模標準。使強大的視覺設計,執行和維護軟體等工序成為可能。並且,OMG還制定了廣為人知的中介軟體標準Common Object Request Broker Architecture (CORBA®)。

通用物件代理體系結構CORBA(Common Object Request Broker Architecture)是OMG所定義的用來實現現今大量硬體、軟體之間互操作的解決方案,CORBA也是邁向面向物件標準化和互操作的重要一步。 

簡單地說,CORBA允許應用之間相互通訊,而不管它們存在於哪裡以及是誰設計的,即跨平臺、跨語言。CORBA1.1於1991年由OMG釋出,其中定義了介面定義語言(IDL)以及在物件請求代理(ORB)中實現客戶物件與伺服器物件之間互動的應用程式設計介面(API)。CORBA2.0於1994年釋出,規定了各個供應商之間的ORB的通訊規則。

CORBA標準主要分為三個部分

:介面定義語言(IDL)、物件請求代理(ORB)以及ORB之間的互操作協議IIOP。 

IDL是CORBA定義的語言,CORBA還定義了IDL到各種語言的對映,標準對映的有Ada、C、C++、Smalltalk、Java、以及Python。有了這些對映,就可以將IDL翻譯成各種語言,從而實現了跨語言。IDL語言是一種介面定義語言。IDL語言不同於所有已有的程式設計語言,它是一種描述性語言,也就是說,用它描述得到的介面是不能直接被編譯執行。OMG IDL語言採用ISOLatin-1(8859.1)字符集。該字符集可以分為字母、數字、圖形符號、空格符、和格式符號。其中字母包括英文26個字母的大小寫,數字包括10個阿拉伯數字0到9。

ORB是CORBA的核心,是物件之間建立Client/Server關係的中介軟體。使用ORB,客戶可以透明地呼叫一個服務物件上的方法,這個服務物件可以在本地,也可以在通過網路連線的其他機器上。ORB截獲這一呼叫同時負責查詢實現服務的物件並向其傳遞引數、呼叫方法返回最終結果。客戶並不知道服務物件位於什麼地方,它的程式語言和作業系統是什麼,也不知道不屬於物件介面的其他系統部分。這樣,ORB在異構分佈環境下為不同機器上的應用提供了互操作性,並無縫地集成了多種物件系統。

CORBA的基本結構如下:

         

在client端去呼叫server端的程式碼時,ORB對於client端是不可見的,client感覺好像呼叫了自己物件的方法一樣,但是網路傳輸的過程都被封裝在了ORB中。

CORBA和Java都採用面向物件技術,因此,可以很容易地用Java語言開發CORBA應用,或將Java應用以及JavaBean物件整合到CORBA應用環境中;CORBA和Java都適用於開發分散式應用,所不同的是:CORBA偏重於通用的分散式應用開發,而Java注重於WWW環境中的分散式應用開發

使用CORBA開發的小例子

如果想開發一個CORBA的Helloworld,基本上有以下幾個步驟:

1.使用idl語言開發idl檔案,這個檔案中描述了介面的定義


  
  1. module helloworld{
  2. interface HelloWorld{
  3. string sayHello();
  4. };
  5. };
module:對應了java中的package

interface:對應了java中的interface,HelloWorld即介面名稱

sayHello:對應了java中interface宣告的方法

string:對應了java中方法的返回值

2.使用java中的idlj命令,將idl語言翻譯成java語言,並生成java程式碼

將idl檔案拷貝到%JAVA_HOME%\bin下,然後在命令列下切換到bin目錄下執行:

idlj -fall helloworld.idl
  
idlj:java自帶的工具

-fall:生成server和client端程式碼,也可以單獨生成server或client

helloworld.idl:之前建立的idl檔案

此時,在bin目錄下就會生成helloworld資料夾,資料夾中會有6個檔案,將這6個拷回eclipse工程中。注意:檔案中的包名就是idl中生命的helloworld。如下圖:

        

這時_HelloWorldStub.java、HelloWorld.java、HelloWorldHelper.java、HelloWorldHolder.java、HelloWorldOperations.java是client需要的程式碼;HelloWorld.java、HelloWorldOperations.java、HelloWorldPOA.java是server需要的程式碼。

簡單看一下自動生成的這幾個檔案:

HelloWorld.java,與idl中的介面名一模一樣,但是實際上只是一個標識介面沒有任何的實現


  
  1. package helloworld;
  2. /**
  3. * helloworld/HelloWorld.java .
  4. * Generated by the IDL-to-Java compiler (portable), version "3.2"
  5. * from helloworld.idl
  6. * Friday, May 16, 2014 2:13:26 PM CST
  7. */
  8. public interface HelloWorld extends HelloWorldOperations, org.omg.CORBA.Object, org.omg.CORBA.portable.IDLEntity
  9. {
  10. } // interface HelloWorld
HelloWorldOperations.java,是idl中宣告的介面

  
  1. package helloworld;
  2. /**
  3. * helloworld/HelloWorldOperations.java .
  4. * Generated by the IDL-to-Java compiler (portable), version "3.2"
  5. * from helloworld.idl
  6. * Friday, May 16, 2014 2:13:26 PM CST
  7. */
  8. public interface HelloWorldOperations
  9. {
  10. String sayHello ();
  11. } // interface HelloWorldOperations
_HelloWorldStub.java、HelloWorldHelper.java、HelloWorldHolder.java是client的樁和工具類;HelloWorldPOA.java是server的實現介面的類(大概是這個意思吧,不太懂),看著比較暈,就不貼了。

3.開發server端的程式碼

既然開發了介面定義,也翻譯成了java程式碼,那麼就要寫介面的實現了,實現是在server端的,需要繼承自的HelloWorldPOA


  
  1. package server;
  2. import helloworld.HelloWorldPOA;
  3. /**
  4. * 伺服器端的實現程式碼
  5. *
  6. */
  7. public class HelloWorldImpl extends HelloWorldPOA {
  8. @Override
  9. public String sayHello() {
  10. return "Hello World!";
  11. }
  12. }
server啟動的程式碼,這段程式碼主要功能是將介面實現註冊到ORB中,並啟動監聽,等待client來呼叫

  
  1. package server;
  2. import helloworld.HelloWorld;
  3. import helloworld.HelloWorldHelper;
  4. import org.omg.CORBA.ORB;
  5. import org.omg.CORBA.ORBPackage.InvalidName;
  6. import org.omg.CosNaming.NameComponent;
  7. import org.omg.CosNaming.NamingContextExt;
  8. import org.omg.CosNaming.NamingContextExtHelper;
  9. import org.omg.CosNaming.NamingContextPackage.CannotProceed;
  10. import org.omg.CosNaming.NamingContextPackage.NotFound;
  11. import org.omg.PortableServer.POA;
  12. import org.omg.PortableServer.POAHelper;
  13. import org.omg.PortableServer.POAManagerPackage.AdapterInactive;
  14. import org.omg.PortableServer.POAPackage.ServantNotActive;
  15. import org.omg.PortableServer.POAPackage.WrongPolicy;
  16. public class HelloServer {
  17. public static void main(String[] args) throws ServantNotActive, WrongPolicy, InvalidName, AdapterInactive, org.omg.CosNaming.NamingContextPackage.InvalidName, NotFound, CannotProceed {
  18. //指定ORB的埠號 -ORBInitialPort 1050
  19. args = new String[ 2];
  20. args[ 0] = "-ORBInitialPort";
  21. args[ 1] = "1050";
  22. //建立一個ORB例項
  23. ORB orb = ORB.init(args, null);
  24. //拿到RootPOA的引用,並激活POAManager,相當於啟動了server
  25. org.omg.CORBA.Object obj=orb.resolve_initial_references( "RootPOA");
  26. POA rootpoa = POAHelper.narrow(obj);
  27. rootpoa.the_POAManager().activate();
  28. //建立一個HelloWorldImpl例項
  29. HelloWorldImpl helloImpl = new HelloWorldImpl();
  30. //從服務中得到物件的引用,並註冊到服務中
  31. org.omg.CORBA.Object ref = rootpoa.servant_to_reference(helloImpl);
  32. HelloWorld href = HelloWorldHelper.narrow(ref);
  33. //得到一個根名稱的上下文
  34. org.omg.CORBA.Object objRef = orb.resolve_initial_references( "NameService");
  35. NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef);
  36. //在命名上下文中繫結這個物件
  37. String name = "Hello";
  38. NameComponent path[] = ncRef.to_name(name);
  39. ncRef.rebind(path, href);
  40. //啟動執行緒服務,等待客戶端呼叫
  41. orb.run();
  42. System.out.println( "server startup...");
  43. }
  44. }
4.開發client端的程式碼

server端的實現與服務監聽都已經做完,現在需要寫一個client來呼叫server的方法


  
  1. package client;
  2. import helloworld.HelloWorld;
  3. import helloworld.HelloWorldHelper;
  4. import org.omg.CORBA.ORB;
  5. import org.omg.CORBA.ORBPackage.InvalidName;
  6. import org.omg.CosNaming.NamingContextExt;
  7. import org.omg.CosNaming.NamingContextExtHelper;
  8. import org.omg.CosNaming.NamingContextPackage.CannotProceed;
  9. import org.omg.CosNaming.NamingContextPackage.NotFound;
  10. public class HelloClient {
  11. static HelloWorld helloWorldImpl;
  12. static {
  13. System.out.println( "client開始連線server.......");
  14. //初始化ip和埠號,-ORBInitialHost 127.0.0.1 -ORBInitialPort 1050
  15. String args[] = new String[ 4];
  16. args[ 0] = "-ORBInitialHost";
  17. //server端的IP地址,在HelloServer中定義的
  18. args[ 1] = "127.0.0.1";
  19. args[ 2] = "-ORBInitialPort";
  20. //server端的埠,在HelloServer中定義的
  21. args[ 3] = "1050";
  22. //建立一個ORB例項
  23. ORB orb = ORB.init(args, null);
  24. // 獲取根名稱上下文
  25. org.omg.CORBA.Object objRef = null;
  26. try {
  27. objRef = orb.resolve_initial_references( "NameService");
  28. } catch (InvalidName e) {
  29. e.printStackTrace();
  30. }
  31. NamingContextExt neRef = NamingContextExtHelper.narrow(objRef);
  32. String name = "Hello";
  33. try {
  34. //通過ORB拿到了server例項化好的實現類
  35. helloWorldImpl = HelloWorldHelper.narrow(neRef.resolve_str(name));
  36. } catch (NotFound e) {
  37. e.printStackTrace();
  38. } catch (CannotProceed e) {
  39. e.printStackTrace();
  40. } catch (org.omg.CosNaming.NamingContextPackage.InvalidName e) {
  41. e.printStackTrace();
  42. }
  43. System.out.println( "client connected server.......");
  44. }
  45. public static void main(String args[]) throws Exception {
  46. sayHello();
  47. }
  48. //呼叫實現類的方法
  49. public static void sayHello() {
  50. String str = helloWorldImpl.sayHello();
  51. System.out.println(str);
  52. }
  53. }
我們可以看到在server和client個建立了一個ORB的例項,這時因為在server和client都需要有支援通訊(見上面的CORBA基本結構圖)。

5.啟動orbd服務

僅僅建立了server和client的程式碼還不足以跑起來一個HelloWorld,還需要啟動一個orbd服務,這個服務在%JAVA_HOME%\jre\bin下。orbd包含自啟動服務、透明的命名服務、持久化命名服務和命名管理器的後臺處理程序。應該是上面的HelloWorld用到了nameService所以才會需要這個服務,使用其他方式拿server的例項是不是就不需要這個服務了,又或者是所有的CORBA都要與這個服務通訊,不太明白?

在命令列下輸入啟動orbd:


  
  1. cd /d %JAVA_HOME%\bin
  2. orbd -ORBInitialPort 1050 -ORBInitialHost 127.0.0.1

6.啟動server服務

7.啟動client

可以看到輸出結果:


  
  1. client開始連線 server.......
  2. client connected server.......
  3. Hello World!

現在CORBA用的已經很少了,基本上只有一些大的電信專案還在用,現在同類的解決方案中WebService是比較流行的。


				<script>
					(function(){
						function setArticleH(btnReadmore,posi){
							var winH = $(window).height();
							var articleBox = $("div.article_content");
							var artH = articleBox.height();
							if(artH > winH*posi){
								articleBox.css({
									'height':winH*posi+'px',
									'overflow':'hidden'
								})
								btnReadmore.click(function(){
									articleBox.removeAttr("style");
									$(this).parent().remove();
								})
							}else{
								btnReadmore.parent().remove();
							}
						}
						var btnReadmore = $("#btn-readmore");
						if(btnReadmore.length>0){
							if(currentUserName){
								setArticleH(btnReadmore,3);
							}else{
								setArticleH(btnReadmore,1.2);
							}
						}
					})()
				</script>
				</article>