12: 多语言互通互联

来源:互联网 发布:中国自然保护区数据库 编辑:程序博客网 时间:2024/05/01 09:00

Ice的服务端可以采用C++/Java/Python/C#等实现,客户端可以采用C++/Java/Python/C#/VB/PHP/Ruby来实现,

就是说我的一个服务端采用C++实现,客户端可以采用java/php/vb/c# 等其他语言实现。 


这个特性也是Ice的很重要的优势之一. 

Ice的多语言之间如何确保对象的正确传输,每种语言都有各自的特点,数据类型,Ice是如何达到各种语言之间的互通互联的呢? 
那么就一定提到Slice语言.Slice是保证各种语言的互通互联的关键,它是独立于其它任何语言,Ice可以通过把Slice代码片断转化为各自的 


Slice的全称:Specification Language for Ice,是Ice自己的特殊语言,一种用于使对象接口与其实现相分离的基础性抽象机制。Slice 建立在客户与服务器之间的合约,用以描述应用所使用的类型和对象接口。Slice描述独立于实现语言,所以客户实现语言是否与编写服务器所用的语言相同没有任何关系。 

slice语言片段可以被编译为任何所支持语言的实现。目前Ice Slice可以支持映射到到C++, Java, C#, Python,Ruby, and PHP。 
因为Slice主要对接口和类型的定义和描述,没有实现部分。 

到底如何实现不同语言的互通互联的呢?我们已Java,C++作为Ice例子原形,实际上我们仅仅做少量修改,就可以实现 

C++的服务端,Java的客户端。Server和Client还是保持在同一台机器上运行。注意我们基于同一个demo.ice的事例。 

首先运行./Server,再运行Client,看到结果了么?赫赫,是不是出现了正常结果。 

到目前没有我们所有实例都是基于同一台机器的,实际情况Server,Client会分布在不同机器上。这种情况下,我们需要如何处理呢? 


这个很简单,在Server少量修改 
Java代码  
  1. Ice::ObjectAdapterPtr adapter  =   ic->createObjectAdapterWithEndpoints ("TestAdapter",                                "default -p 10000");  


"default -p 10000" 采用 "tcp -h server1 -p port" 替代 

Server所在主机IP:172.17.12.101 ,端口:10000 

所以就修改为:tcp -h 172.17.12.101 -p 10000,再重新编译Server 

Java代码  
  1. #include <Ice/Ice.h>  
  2. #include <demo.h>  
  3. using namespace std;  
  4. using namespace Demo;  
  5. class Server:public test  
  6. {  
  7. public:  
  8.   ::std::string execute (const string & mth, const string & str,  
  9.                          const Ice::Current &);  
  10. public:  
  11.     Server ();  
  12. };  
  13. Server::Server ()  
  14. {  
  15.    
  16. };  
  17. std::string Server::execute (const string & mth, const string & str,  
  18.                              const Ice::Current &)  
  19. {  
  20.   cout << mth + str << endl;  
  21.   return mth + str;  
  22. }  
  23.    
  24. int  
  25. main (int argc, char *argv[])  
  26. {  
  27.   int  
  28.     status = 0;  
  29.   Ice::CommunicatorPtr ic;  
  30.   try  
  31.   {  
  32.     ic = Ice::initialize (argc, argv);  
  33.     Ice::ObjectAdapterPtr adapter  
  34.       =  
  35.       ic->createObjectAdapterWithEndpoints ("TestAdapter",  
  36.                                             "tcp -h 172.17.12.101 -p 10000");  
  37.     Ice::ObjectPtr object = new Server;  
  38.     adapter->add (object, ic->stringToIdentity ("TestAdapter"));  
  39.     adapter->activate ();  
  40.     ic->waitForShutdown ();  
  41.   } catch (const Ice::Exception & e)  
  42.   {  
  43.     cerr << e << endl;  
  44.     status = 1;  
  45.   } catch (const char *msg)  
  46.   {  
  47.     cerr << msg << endl;  
  48.     status = 1;  
  49.   }  
  50.   if (ic)  
  51.     {  
  52.       try  
  53.       {  
  54.         ic->destroy ();  
  55.       }  
  56.       catch (const Ice::Exception & e)  
  57.       {  
  58.         cerr << e << endl;  
  59.         status = 1;  
  60.       }  
  61.     }  
  62.   return status;  
  63. }  


下面我们需要对Client连接部分进行修改,同理: 
Java代码  
  1. Ice.ObjectPrx base = ic.stringToProxy("TestAdapter:tcp -h 172.17.12.101 -p 10000");  


Java代码  
  1. package Demo;  
  2.   
  3. public class Client {  
  4.     public static void main(String[] args) {  
  5.         int status = 0;  
  6.         Ice.Communicator ic = null;  
  7.         try {  
  8.             ic = Ice.Util.initialize(args);  
  9. //          Ice.ObjectPrx base = ic  
  10. //                  .stringToProxy("SimplePrinter:tcp -h 172.17.12.101 -p 10000");  
  11.             Ice.ObjectPrx base = ic  
  12.             .stringToProxy("TestAdapter:tcp -h 172.17.12.101 -p 10000");  
  13.   
  14.             testPrx test = testPrxHelper.checkedCast(base);  
  15.             if (test == null)  
  16.                 throw new Error("Invalid proxy");  
  17.             System.out.println(test.execute("My first Ice ""事例"));  
  18.             //System.out.println("ok");  
  19.         } catch (Ice.LocalException e) {  
  20.             e.printStackTrace();  
  21.             status = 1;  
  22.         } catch (Exception e) {  
  23.             System.err.println(e.getMessage());  
  24.             status = 1;  
  25.         }  
  26.         if (ic != null) {  
  27.             // Clean up  
  28.             //  
  29.             try {  
  30.                 ic.destroy();  
  31.             } catch (Exception e) {  
  32.                 System.err.println(e.getMessage());  
  33.                 status = 1;  
  34.             }  
  35.         }  
  36.         System.exit(status);  
  37.     }  
  38. }  

看到了么,就是这么简单,其他部分不用修改。 

好了,我们进行验证,首先启动./Server,再执行Client ,看到了 

"My first Ice 事例" 看到了么,祝贺你,跨语言的分布式调用例子你已经实现了。 


其实Ice的通讯机制极其强大,支持集群和容错技术。关于集群的事例会在日后的文章中介绍。 

BTW: 

注意,Server运行之后监听于10000端口,需要修改iptables,允许其他机器可以连接。 
编辑 iptables 
vi /etc/sysconfig/iptables 
追加: 
Java代码  
  1. -A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 10000 -j ACCEPT  
0 0
原创粉丝点击