天天看點

【通信中間件】電信級解決方案中間件ICE程式設計入門指南

0.ICE介紹:ICE(Internet Communications Engine)是ZeroC提供的一款高性能的中間件,基于ICE可以實作電信級的解決方案。個人了解與COBRA貌似基本上是一個作用的東西,由于項目上要用到,早上簡單實用了一下,還是很友善的。

1.開發流程:

編寫ICE接口檔案=>選擇開發語言,生成相關類和接口=>開發Server端=>開發Client端=>部署Server端=>運作Client

2.安裝:

環境:Ubuntu 9.10

$sudo apt-get install zeroc-*

3.執行個體:編寫一個名為shareiceserver 的子產品,裡面有一個名為Sonics的接口

1)編寫ICE檔案:

module shareiceserver {     interface Sonics{         int authenUser(string userID, string password);         bool isOrdered(string userID, string appID);// SONICS查詢某使用者是否訂購某業務:傳回值bool         bool checkBalanceByName(string userID, double balance);         string getHomeSCSByUserID(string userID);//SONICS查詢某使用者歸屬SCS資訊:傳回值            }; }; //shareiceserver

在這個子產品中,我們定義了一個接口,請注意這個接口與Java中的接口并不是一個概念,在後邊自動生成代碼時會生成一系列類和接口。

将這個檔案儲存為shareiceserver.ice

2)選擇開發語言:

生成接口和類檔案

slice2java shareiceserver.ice

此時會産生一個叫做shareiceserver的檔案夾:

sam@sam-desktop:~/ICE/shareiceserver$ ls _SonicsDelD.java  _SonicsDelM.java  SonicsHolder.java  _SonicsOperations.java    SonicsPrxHelper.java  SonicsPrx.java _SonicsDel.java   _SonicsDisp.java  Sonics.java        _SonicsOperationsNC.java  SonicsPrxHolder.java

3)開發Server端(傳統方法)

a.添加定義的方法的具體實作:SonicsI.java

public class SonicsI extends shareiceserver._SonicsDisp{         public int authenUser(String userID, String password, Ice.Current current)         {                 return 0;         }         public boolean checkBalanceByName(String userID, double balance, Ice.Current current)                 return true;         public String getHomeSCSByUserID(String userID ,Ice.Current current)         {                               return userID+":192.168.0.1";         public boolean isOrdered(String userID, String appID, Ice.Current current) }

繼承_SonicsDisp建立servant類SonicsI(一般我們在接口的名字後邊加上I表示servant類),_SonicsDisp是自動生成的,這是個抽象類,包含了我們要實作的方法的原型(隻是每一個方法都加入了一個Ice.Current類型的參數)。我們這裡隻是示意性的對方法進行了實作,沒有什麼具體的邏輯。

.b.編寫Server端主程式代碼:Server.java

public class Server {     public static void     main(String[] args)     {         int status = 0;         Ice.Communicator ic = null;         try {             ic = Ice.Util.initialize(args);//初始化Ice,傳回一個Ice::Communicator引用作為Ice的運作操作句柄。             Ice.ObjectAdapter adapter//在此Ice環境下建立一個對象擴充卡(名為SimpleSonics),default為使用預設協定TCP/IP,并使用端口10000。初始化至此完成。                 = ic.createObjectAdapterWithEndpoints(                     "SimpleSonics", "default -p 10000");             Ice.Object object = new SonicsI();//建立一個servant執行個體。             adapter.add(                     object,                     Ice.Util.stringToIdentity("SimpleSonics"));//将這個servant執行個體加入對象擴充卡,并且指明名稱。             adapter.activate();//激活擴充卡             ic.waitForShutdown();//這個調用将該線程挂起直到Server終止。在這裡,我們簡單使用指令行終止的方式。         } catch (Ice.LocalException e) {             e.printStackTrace();             status = 1;         } catch (Exception e) {             System.err.println(e.getMessage());         if (ic != null) {             // Clean up             //             try {                 ic.destroy();//在程式退出之前要對Ice整個環境進行銷毀。             } catch (Exception e) {                 System.err.println(e.getMessage());                 status = 1;             }         System.exit(status);     }

在編寫Server端程式時,我們要對ICE和以及程式邏輯運作時可能抛出的異常做處理,然後再注冊啟動Server端。

編譯:(在ubuntu環境下Ice.jar的位置如下,其他環境需要修改)

$mkdir classes $javac Server.java SonicsI.java shareiceserver/*.java -classpath /usr/share/java/Ice.jar -d classes

4)編寫Client端主程式代碼:Client.java

public class Client {             ic = Ice.Util.initialize(args);//初始化Ice環境             Ice.ObjectPrx base = ic.stringToProxy(//添加一個代理,設定名字、協定、端口。傳回接口與類的繼承樹的根部                    "SimpleSonics:default -p 10000");            shareiceserver.SonicsPrx sonicser                 =shareiceserver.SonicsPrxHelper.checkedCast(base);//沿着這個繼承樹尋找Sonics             if (sonicser== null)//若無法找到則傳回null,至此準備工作完成。                 throw new Error("Invalid proxy");             System.out.println(sonicser.getHomeSCSByUserID("001"));//具體方法調用                 ic.destroy();//銷毀Ice環境

編譯:

javac Client.java shareiceserver/*.java -classpath /usr/share/java/Ice.jar -d classes

5)部署運作:

環境配置:(否則出現NoClassDefFoundError: Ice/LocalException異常)

export CLASSPATH=$CLASSPATH:./classes:/usr/share/java/Ice.jar

Server端運作:

~/ICE/classes$ java Server &

Client端運作:

~/ICE/classes$ java Client

運作結果:

001:192.168.0.1

4.使用Ice.Application建立Server和Client端

Server端:Server1.java

public class Server1 extends Ice.Application {     public int     run(String[] args)         Ice.Communicator ic = communicator();          Ice.ObjectAdapter adapter             Ice.Object object = new SonicsI();                     Ice.Util.stringToIdentity("SimpleSonics"));             adapter.activate();             ic.waitForShutdown();         return 0;         Server1 app = new Server1();         int status = app.main("Server1", args);

Client端:Client1.java

public class Client1 extends Ice.Application {         Ice.Communicator ic = Ice.Util.initialize(args);         Ice.ObjectPrx base = ic.stringToProxy(             "SimpleSonics:default -p 10000");         shareiceserver.SonicsPrx sonicser             =shareiceserver.SonicsPrxHelper.checkedCast(base);         if (sonicser== null)             throw new Error("Invalid proxy");         System.out.println(sonicser.getHomeSCSByUserID("001"));         Client1 app = new Client1();         int status = app.main("Client1", args);

使用這個類的好處是程式清晰,并且自動在其中提供了信号處理、配置等功能。編譯方法與上相同。

5.關閉信号的捕捉

在Ice.Application中,在JVM關閉之前程式預設調用destroyOnInterrupt這個回調函數完成一些clean和hint的工作:

if(interrupted())                System.err.println(appName()+ ": terminating");        return 0;

但是這個預設的回調函數在主程式阻塞時(比如主程式接收鍵盤輸入時)不會被調用,為了克服這一特點,我們可以自己注冊一個回調函數:

public class Server extends Ice.Application {     class ShutdownHook extends Thread {         public voidrun()         {             try             {                 communicator().destroy();             }             catch(Ice.LocalException ex)                 ex.printStackTrace();         }     }      public intrun(String[] args)     {         setInterruptHook(new ShutdownHook());         // ...