小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

用ICE開發(fā)分布式程序

 quasiceo 2016-07-14

分類:

ICE是ZeroC公司開發(fā)的一款高效的開源中間件平臺,全稱是Internet Communications Engine。

它的主要設(shè)計(jì)目標(biāo)是:
 提供適用于異種環(huán)境的面向?qū)ο笾虚g件平臺。
 提供一組完整的特性,支持廣泛的領(lǐng)域中的實(shí)際的分布式應(yīng)用的開發(fā)。
 避免不必要的復(fù)雜性,使平臺更易于學(xué)習(xí)和使用。
 提供一種在網(wǎng)絡(luò)帶寬、內(nèi)存使用和 CPU 開銷方面都很高效的實(shí)現(xiàn)。
 提供一種具有內(nèi)建安全性的實(shí)現(xiàn),使它適用于不安全的公共網(wǎng)絡(luò)。

ICE支持多種編程語言:C++、Java、C#、VB、Python、Ruby,也就是說使用ICE時我們可以讓這些語言無縫溝通,不過由于ICE是用C++編寫的,不管用什么語言,你都需要先用C++編譯出一個ICE才行(或者下載已編譯的版本)。

本篇文章以C++語言作為演示語言,其它語言除語法不同外,使用方法非常類似。
 

配置ICE開發(fā)環(huán)境

首先,從http://www./download.html 下載ICE,目前最新版本是Ice-3.3.1。下載頁面里除了ICE的源碼之外,也提供了VC或C++Builder的已編譯安裝包以及各Linux版本的RPM下載。

如果下載的是源碼版本,編譯方法是(以VC2005 Express為例):

1. ICE需要一些第三方庫,在編譯ICE之前要先編譯第三方庫,清單如下(它們也能在ICE官網(wǎng)上下載):

Berkeley DB
expat
OpenSSL
bzip2
mcpp

2. 編譯完上面這些庫以后,把它們放到同一個目錄中,然后設(shè)置環(huán)境變量THIRDPARTY_HOME:

set THIRDPARTY_HOME = d:\ice3party

3. 打開$ICE/cpp/Make.rules.mak,找到CPP_COMPILER變量,改成CPP_COMPILER = VC80_EXPRESS
    這個依據(jù)你的編譯器決定,可以是VC60, VC80, VC80_EXPRESS, VC90, VC90_EXPRESS, BCC2007, BCC2009

4. 如果想讓編譯的庫能脫離VC運(yùn)行時庫,打開$ICE/cpp/Make.rules.msvc,把CPPFLAGS    = $(CPPFLAGS) -MD改成CPPFLAGS    = $(CPPFLAGS) -MT。

5. 在命令行下進(jìn)入$ICE/cpp目錄,輸入nmake -f Makefile.mak開始編譯。默認(rèn)是編譯成Debug模式的DLL庫。如果想編譯成靜態(tài)庫,可以設(shè)置變量STATICLIBS=yes;想編譯成Release模式,設(shè)置OPTIMIZE=yes。如

nmake -f Makefile.mak STATICLIBS=yes OPTIMIZE=yes

如果按上面方法設(shè)置,應(yīng)該不會有問題。

6. 最最后,把bin目錄加入path變量,以便讓系統(tǒng)能找到ICE的dll文件(其實(shí)主要是三個dll文件,ice33.dll、iceutil33.dll和bzip2.dll)

以后編譯ICE的程序時,把上面編譯好或直接下載的已編譯版本的ice.lib和iceutil.lib(或Debug版本的iced.lib和iceutild.lib)鏈接入項(xiàng)目即可。


ICE的HelloWorld

跨語言的分布式系統(tǒng)首先要定義一個與編程語言無關(guān)的接口描述語法,用于分布于各處的服務(wù)器與客戶端之間對話。比如DCOM和CORBA使用IDL語法,SOAP使用WSDL語法,當(dāng)然還有時下流行的JSON。

ICE使用的是稱為Slice(Specificatoin Language for Ice)的語法,Slice語法和C++(或Java,C#)比較相近,只要會C++(或Java,C#)很容易就能寫Slice定義了

下面是一個簡單的接口的Slice定義:

  1. module Demo {
  2.     interface Printer {
  3.         void printString(string s);
  4.     };
  5. };

它定義一個Printer接口(interface),這個接口只有一個printString方法,輸入?yún)?shù)是一個字符串(string)。最后,這個接口位于Demo模塊(module)之下。

把它保存為Printer.ice后接著我們使用slice2cpp程序依據(jù)這個Slice定義生成C++使用的頭文件和對應(yīng)的代理代碼:

slice2cpp Printer.ice

如果沒提示錯誤,就會生成Printer.h和Printer.cpp,把這兩個文件加入到服務(wù)器端項(xiàng)目和客戶端項(xiàng)目后就可以互相對話了。

下表是Slice與C++的映射關(guān)系

Slice C++
#include #include
#ifndef #ifndef
#define #define
#endif #endif
module namespace
bool bool
byte Ice::Byte
short Ice::Short
int Ice::Int
long Ice::Long
float Ice::Float
double Ice::Double
string Ice::string
enum enum(不支持指定數(shù)字)
struct struct
class class(所有方法都是純虛函數(shù))
interface struct(所有方法都是純虛函數(shù),沒有成員變量)
sequence std::vector
dictionary std::map
exception Err class Err:public Ice:UserException
nonmutating方法限定符 const方法
idempotent方法限定符 -
out 參數(shù)限定符 引用類型
* 對應(yīng)類型的代理類

參考這個表,可以知道上面的Slice定義對應(yīng)的C++映射如下:

  1. namespace Demo {
  2.     struct Printer {
  3.         virtual void printString(string s) = 0;
  4.     };
  5. };

嚴(yán)格地說,C++中對應(yīng)的Printer類還繼承自IceProxy::Ice::Object,目前我們可以不理這個問題

我們只要在服務(wù)器端實(shí)現(xiàn)這個printString方法,就可以在客戶端簡單地調(diào)用它了。

編寫服務(wù)器端代碼:

  1. 新建一個控制臺項(xiàng)目
  2. 將$ICE\include添加到頭文件目錄列表中
  3. 將$ICE\lib\ice.lib和iceutil.lib(對應(yīng)的Debug版本是iced.lib和iceutild.lib)鏈接入項(xiàng)目
  4. 把生成Printer.cpp加入項(xiàng)目
  1. #include 
  2. #include "printer.h"  //slice2cpp生成的文件

  3. using namespace std;
  4. using namespace Demo;

  5. //實(shí)現(xiàn)printString方法
  6. struct PrinterImp : Printer{
  7.     virtual void printString(const ::std::string& s,
  8.         const ::Ice::Current& = ::Ice::Current())
  9.     {
  10.         cout << s << endl;   
  11.     }
  12. };

  13. int main(int argc, char* argv[])
  14. {
  15.     Ice::CommunicatorPtr ic;

  16.     try{
  17.         // 初始化Ice運(yùn)行庫
  18.         ic = Ice::initialize(argc, argv);
  19.         // 建立ObjectAdapter,命名為SimplePrinterAdapter
  20.         // 使用默認(rèn)協(xié)議(一般是tcp)并在10000端口監(jiān)聽。
  21.         Ice::ObjectAdapterPtr adapter
  22.             = ic->createObjectAdapterWithEndpoints(
  23.                 "SimplePrinterAdapter""default -p 10000");
  24.         // 把我們實(shí)現(xiàn)的Printer加入ObjectAdapter,并命名為SimplePrinter
  25.         Ice::ObjectPtr object = new PrinterImp;
  26.         adapter->add(object, ic->stringToIdentity("SimplePrinter"));
  27.         adapter->activate();
  28.         // 等待直到Communicator關(guān)閉
  29.         ic->waitForShutdown();
  30.     }
  31.     catch(const Ice::Exception &e){
  32.         cerr << e << endl;
  33.     }
  34.     catch(const char* msg){
  35.         cerr << msg << endl;
  36.     }
  37.     // 回收Ice運(yùn)行庫所用的資源
  38.     if(ic) ic->destroy();
  39.    
  40.     return 0;
  41. }

客戶端代碼:

  1. #include 
  2. #include 

  3. using namespace std;
  4. using namespace Demo;

  5. int main(int argc, char* argv[])
  6. {
  7.     Ice::CommunicatorPtr ic;
  8.     try{
  9.         // 初始化Ice運(yùn)行庫
  10.         ic = Ice::initialize(argc, argv);
  11.         // 在10000端口取得SimplePrinter代理對象
  12.         Ice::ObjectPrx base = ic->stringToProxy("SimplePrinter:default -p 10000");
  13.         // 把對象轉(zhuǎn)換成Printer代理
  14.         PrinterPrx printer =  PrinterPrx::checkedCast(base);
  15.         if(!printer) throw "Invalid Proxy!";
  16.         // 能過這個代碼調(diào)用printString方法
  17.         printer->printString("Hello World!");
  18.     }
  19.     catch(const Ice::Exception &e){
  20.         cerr << e << endl;
  21.     }
  22.     catch(const char* msg){
  23.         cerr << msg << endl;
  24.     }
  25.     // 回收Ice運(yùn)行庫所用的資源
  26.     if(ic) ic->destroy();
  27.    
  28.     return 0;
  29. }

編譯服務(wù)器端和客戶端,然后啟動一個服務(wù)器端,每次調(diào)用客戶端后服務(wù)器端會顯示一行Hello world!

你也可以把服務(wù)器端放到別的電腦上,客戶端代碼改成:Ice::ObjectPrx base = ic->stringToProxy("SimplePrinter:default -h 服務(wù)端IP -p 10000");即可實(shí)現(xiàn)遠(yuǎn)程調(diào)用。

看上去我們寫一個Helloworld的程序要弄這么一大堆的東西,不過實(shí)際上只要我們修改Slice定義,我們就可實(shí)現(xiàn)更強(qiáng)大的功能,而代碼并不需要多大變化。

使用Ice::Application簡化代碼的編寫

對比上例中的服務(wù)端和客戶端代碼,可以發(fā)現(xiàn)占很大比例的代碼都是初始化、異常捕捉、回收資源這樣的“樣板”代碼。ICE針對這些“樣板”代碼提供了Ice::Application類來封裝它們(而且它做得更多),通過它我們就可以簡化上例中了代碼了。

Ice::Application中有一個純虛函數(shù)

virtual int run(int, char*[]) = 0;


我們只要實(shí)現(xiàn)這個run方法,其它的一切都由Application完成:

服務(wù)器端:

  1. #include 
  2. #include "printer.h"

  3. using namespace std;
  4. using namespace Demo;

  5. struct PrinterImp : Printer{
  6.     virtual void printString(const ::std::string& s, const ::Ice::Current& = ::Ice::Current())
  7.     {
  8.         cout << s << endl;   
  9.     }
  10. };

  11. class MyApp : public Ice::Application{
  12. public:
  13.     virtual int run(intchar*[]){
  14.         Ice::CommunicatorPtr& ic = communicator();
  15.         Ice::ObjectAdapterPtr adapter
  16.             = ic->createObjectAdapterWithEndpoints(
  17.                 "SimplePrinterAdapter""default -p 10000");
  18.         Ice::ObjectPtr object = new PrinterImp;
  19.         adapter->add(object, ic->stringToIdentity("SimplePrinter"));
  20.         adapter->activate();
  21.         ic->waitForShutdown();
  22.         return 0;
  23.     }
  24. };

  25. int main(int argc, char* argv[])
  26. {
  27.     MyApp app;
  28.     return app.main(argc, argv);
  29. }

原來的版本我們的退出方法只能使用很野蠻的強(qiáng)行退出,現(xiàn)在,服務(wù)端可以檢測到Ctrl+C這樣的退出信號了。

客戶端:

  1. #include 
  2. #include 

  3. using namespace std;
  4. using namespace Demo;

  5. class MyApp: public Ice::Application{
  6. public:
  7.     virtual int run(intchar*[])
  8.     {
  9.         Ice::CommunicatorPtr ic = communicator();
  10.         Ice::ObjectPrx base = ic->stringToProxy("SimplePrinter:default -p 10000");
  11.         PrinterPrx printer =  PrinterPrx::checkedCast(base);
  12.         if(!printer) throw "Invalid Proxy!";
  13.         printer->printString("Hello World!");
  14.     }
  15. };

  16. int main(int argc, char* argv[])
  17. {
  18.     MyApp app;
  19.     return app.main(argc,argv);
  20. }
閱讀(3123) | 評論(0) | 轉(zhuǎn)發(fā)(0) |
相關(guān)熱門文章

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多