Ice -- Hello World 之 服务端

Ice -- Hello World 之 服务端
首先声明我很挫,刚学的。 有很多不会,不明白的地方,虽然是照搬书上的东西,但是自己也写了一些理解,如果您看到错误的话,请您一定要帮我指正。

首先贴个服务端的代码,就是书上的。


 1  #include  < Ice / Ice.h >
 2  #include  < Printer.h >
 3  using   namespace  std;
 4  class  PrinterI :  public  Printer {
 5  public :
 6        virtual   void  printString( const   string   &  s,
 7                                 const  Ice::Current  & );
 8  };
 9  void
10  PrinterI::
11  printString( const   string   &  s,  const  Ice::Current  & )
12  {
13       cout  <<  s  <<  endl;
14  }
15  int
16  main( int  argc,  char *  argv[])
17  {
18        int  status  =   0 ;
19       Ice::CommunicatorPtr ic;
20        try  {
21           ic  =  Ice::initialize(argc, argv);
22           Ice::ObjectAdapterPtr adapter
23                =  ic -> createObjectAdapterWithEndpoints(
24                    " SimplePrinterAdapter " " default -p 10000 " );
25           Ice::ObjectPtr  object   =   new  PrinterI;
26           adapter -> add( object ,
27                        Ice::stringToIdentity( " SimplePrinter " ));
28           adapter -> activate();
29           ic -> waitForShutdown();
30       }  catch  ( const  Ice::Exception  &  e) {
31           cerr  <<  e  <<  endl;
32           status  =   1 ;
33       }  catch  ( const   char   *  msg) {
34           cerr  <<  msg  <<  endl;
35           status  =   1 ;
36       }
37        if  (ic)
38           ic -> destroy();
39        return  status;
40  }
41 

   对于一个只打印一个串的服务器而言,这里的代码似乎有很多。不要担
心这一点:大多数代码都是不会变化的公式化代码。对于这个非常简单的
服务器而言,其代码几乎就由这些公式化代码组成。
   每个 Slice 源文件的一开始都有一条用于包括 Ice.h 的指令,在
Ice.h 中包含了 Ice run time 的各种定义。我们还包括了由 Slice 编译器生成
的 Printer.h,其中含有我们的打印机接口的 C++ 定义;为了使以后的
代码保持简洁,我们还导入了 std 名字空间的内容:

1  #include  < Ice / Ice.h >
2  #include  < Printer.h >
3  using   namespace  std;
4 


  我们的服务器实现了一个打印机 servant,其类型是 PrinterI。我们查
看 Printer.h 中的生成的代码,发现了以下内容 (为去掉无关细节,进
行了整理)   :

1  class  Printer :  virtual   public  Ice::Object {
2  public :
3       virtual   void  printString( const  std:: string   & ,
4                                const  Ice::Current  &   =  Ice::Current()
5                              )  =   0 ;
6  };
7 



这个类是ice对Printer.ice编译后生成的骨架类的部分。

骨架类 :


在服务器端,接口映射到骨架类。对于相应的接口上的每个操作,骨架类都有一个对应的纯虚方法
• 和客户端一样,Slice 模块映射到名字相同的C++ 名字空间,所以骨架类定义会放在名字空间Demo 中。
• 骨架类的名字与Slice 接口的名字(Printer)相同。
• 对于Slice 接口中的每个操作,骨架类都有一个对应的纯虚成员函数。
• 骨架类是抽象基类,因为它的成员函数是纯虚函数。
• 骨架类继承自Ice::Object (这个类形成了Ice 对象层次的根)。


再回到servant上来。
servant :

1  class  PrinterI :  public  Printer {
2  public :
3       virtual   void  printString( const   string   &  s,
4                                const  Ice::Current  & );
5  };
6 

printString 方法的实现很简单:它会简单地把它的串参数写到stdout:

1  void
2  PrinterI::
3  printString( const   string   &  s,  const  Ice::Current  & )
4  {
5       cout  <<  s  <<  endl;
6  }
7 
servant 是Ice 对象的物理体现,也就是说,它们是
用具体的编程语言实现的实体,并且在服务器的地址空间中进行实例化。
Servants 为“客户发送的操作调用”提供服务器端行为。
同一个servant 可以向一个或更多对象适配器注册。

按照惯例, servant 类的名字是它们接口的名字加上后缀I,所以Printer
接口的servant 类叫作PrinterI (这只是一个惯例:从Ice run time 的角度来
说,你可以为你的servant 类选用任何你喜欢的名字)。

注意, PrinterI 继承自Demo::PrinerI,也就是说,它派生自它
的骨架类。在定义servant 类时总是使用虚继承是个好主意。严格地说,只
有其实现的接口使用了多继承的servant 才必须使用虚继承;但virtual
关键字并无害处,同时,如果你在开发的中途给接口层次增加多继承, 你
无需回去给你的所有servant 类增加virtual 关键字。
从Ice 的角度来说, PrinterI 类只须实现一个成员函数:继承自骨架的
name 纯虚函数。这使得servant 类成了一个能实例化的具体类。你可以按照
你的实现的需要,增加其他成员函数和数据成员。


接下来是服务器的主程序。注意这段代码的总体结构:

 1  int
 2  main( int  argc,  char *  argv[])
 3  {
 4       int  status  =   0 ;
 5      Ice::CommunicatorPtr ic;
 6       try  {
 7           //  Server implementation here
 8      }  catch  ( const  Ice::Exception  &  e) {
 9          cerr  <<  e  <<  endl;
10          status  =   1 ;
11      }  catch  ( const   char   *  msg) {
12          cerr  <<  msg  <<  endl;
13          status  =   1 ;
14      }
15       if  (ic)
16          ic -> destroy();
17       return  status;
18  }
19 

我们的 try 块的主体含有实际的服务器代码:

 1  ic  =  Ice::initialize(argc, argv);
 2  Ice::ObjectAdapterPtr adapter
 3       =  ic -> createObjectAdapterWithEndpoints(
 4           " SimplePrinterAdapter " " default -p 10000 " );
 5  Ice::ObjectPtr  object   =   new  PrinterI;
 6  adapter -> add( object ,
 7               Ice::stringToIdentity( " SimplePrinter " ));
 8  adapter -> activate();
 9  ic -> waitForShutdown();
10 

这段代码包含以下步骤:
1. 我们调用 Ice::initialize,初始化 Ice run time (我们之所以把
   argc和argv传给这个调用,是因为服务器可能有run time感兴趣的命令
   行参数;就这个例子而言,服务器不需要任何命令行参数)               。
   initialize 调用返回的是一个智能指针,指向一个 Ice::Communicator 对象,这个指针是 Ice run time 的主句柄。
2. 我们调用 Communicator 实例上的
   createObjectAdapterWithEndpoints,创建一个对象适配器。我
   们传入的参数是 "SimplePrinterAdapter" (适配器的名字)和
   "default -p 10000",后者是要适配器用缺省协议 (TCP/IP)在端
   口 10000 处侦听到来的请求。
3. 这时,服务器端 run time 已经初始化,我们实例化一个 PrinterI 对
   象,为我们的 Printer 接口创建一个 servant。
4. 我们调用适配器的 add,告诉它有了一个新的 servant ;传给 add 的参
   数是我们刚才实例化的 servant,再加上一个标识符。在这里,
   "SimplePrinter" 串是 servant 的名字(如果我们有多个打印机,每个
   打印机都可以有不同的名字,更正确的说法是,都有不同的对象标
   识) 。

5. 接下来,我们调用适配器的 activate 方法激活适配器 (适配器一开
   始是在扣留 (holding)状态创建的;这种做法在下面这样的情况下很
   有用:我们有多个 servant,它们共享同一个适配器,而在所有 servant
   实例化之前我们不想处理请求)     。一旦适配器被激活,服务器就会开始
   处理来自客户的请求。
6. 最后,我们调用 waitForShutdown。这个方法挂起发出调用的线程,
   直到服务器实现终止为止——或者是通过发出一个调用关闭 run time,或者是对某个信号作出响应




假定我们的服务器代码放在一个叫作 Server.cpp 的文件中,我们可以这样编译它:

$ c++ -I. -I$ICE_HOME/include -c Printer.cpp Server.cpp

   最后,我们需要把服务器链接成可执行程序:
$ c++ -o server Printer.o Server.o -L$ICE_HOME/lib -lIce -lIceUtil



ps : 因为这个命令被袁飞狠狠的BS了一下。。。原来可以合在一起些。。。 55555 我好菜阿






你可能感兴趣的:(Ice -- Hello World 之 服务端)