ZEROC ICE 跨平台间程序调用 java版
前言:
本来建博客是为了和大家分享一些前端的开发经验和心得呢,但是阴差阳错,第一篇技术博客确实关于跨平台,跨语言服务端调用的解决方案---ZEROC ICE。
最近一个项目涉及到java、python、C++三种不同语言间的互相调用。经过反复讨论决定采取ZEROC来实现,在实现的过程中发现网上的很多资料要么很不完整,要么就是过于基础,完全不能满足项目的需要。尤其是对于如何使用ice进行分布式编程介绍更少,除了C++语言外,其他语言的ice使用说明也存在明显不足,虽然不同语言原理一样,但是对于初学者而言,要求还是比较高。所以特地在这里对我们的ice实施解决方案做一个回顾与总结,同时也抛砖引玉,如果有高手发现我们的方案不好,让我也有个二次深入学习的机会!
正文:
本博客系列主要讲解 java语言的ice 客户端、服务端调用、amd服务端异步、客户端调用等。从hello world开始讲解!
一、写一个helloworld的ice文件HelloWorld.ice
- 1 module myHelloWorld{
- 2 interface HelloWorld{
- 3 void say(string s);
- 4 };
- 5 };
module相当于java中的包名;interface对应java中的接口;say对应方法
二、编译这个ice定义
安装一个ice服务器,注意如果大家是不同语言合作开发,那么不同人安装的ice版本最好保持一致,安装linux版本时,注意各种rpm之间的依赖关系。(这里默认大家都会安装,如果不会就去百度去吧,官网上有详尽的说明:https://zeroc.com/)
通过slice2java HelloWorld.ice 来编译ice为java包文件。编译好之后请将改文件夹直接拷贝到工程的src目录下,因为生成的java文件会有对应的包名。为了不报错,必须实际路径和包名一致。同时,到ice的安装目录下,打来lib文件夹,将其中的jar包引入到工程中,确保相关文件没有报错即可。
三、编写Servant类
servant类是ice所定义的接口,在服务器端的实现类。我们在该类中可以编写服务器端对请求的具体处理。
按照管理,servant类名是ice接口名加一个“I”后缀,如下:
- 1 package client;
- 2
- 3 import Ice.Current;
- 4 import myHelloWorld._HelloWorldDisp;
- 5
- 6 public class HelloWorldI extends _HelloWorldDisp{
- 7
- 8 private static final long serialVersionUID = 1L;
- 9
- 10 @Override
- 11 public void say(String s, Current __current) {
- 12 System.out.println("Hello World!"+" the string s is " + s);
- 13 }
- 14 }
四、创建远程的服务器类
初学者建议仔细看看下边的server服务类,该服务类绝大多数代码都是固定格式,只需要根据自己的实际情况变更一下端口、servant的名称、需要加入服务器的servant类即可。
- 1 package client;
- 2 public class Server {
- 3
- 4 public static void main(String[] args)
- 5 {
- 6 int status = 0;
- 7 // Communicator实例,是ice run time的主句柄
- 8 Ice.Communicator ic = null;
- 9 try
- 10 {
- 11 // 调用Ice.Util.Initialize()初始化Ice run time
- 12 System.out.println("初始化ice run time...");
- 13 ic = Ice.Util.initialize(args); //args参数可传可不传
- 14
- 15
- 16 // 创建一个对象适配器,传入适配器名字和在10000端口处接收来的请求
- 17 System.out.println("创建对象适配器,监听端口10000...");
- 18 Ice.ObjectAdapter adapter = ic.createObjectAdapterWithEndpoints("SimplePrinterAdapter", "default -p 10000");
- 19
- 20 // 实例化一个PrinterI对象,为Printer接口创建一个servant
- 21 System.out.println("为接口创建servant...");
- 22 Ice.Object object = new HelloWorldI();
- 23
- 24 // 调用适配器的add,告诉它有一个新的servant,传递的参数是刚才的servant,这里的“SimplePrinter”是Servant的名字
- 25 System.out.println("对象适配器加入servant...");
- 26 adapter.add(object, Ice.Util.stringToIdentity("SimplePrinter"));
- 27
- 28 //调用适配器的activate()方法,激活适配器。被激活后,服务器开始处理来自客户的请求。
- 29 System.out.println("激活适配器,服务器等待处理请求...");
- 30 adapter.activate();
- 31
- 32 //这个方法挂起发出调用的线程,直到服务器实现终止为止。或我们自己发出一个调用关闭。
- 33 ic.waitForShutdown();
- 34 } catch (Ice.LocalException e)
- 35 {
- 36 e.printStackTrace();
- 37 status = 1;
- 38 } catch (Exception e)
- 39 {
- 40 e.printStackTrace();
- 41 status = 1;
- 42 } finally
- 43 {
- 44 if (ic != null)
- 45 {
- 46 ic.destroy();
- 47 }
- 48 }
- 49 System.exit(status);
- 50 }
- 51 }
五、编写客户端类
与服务端一样,客户端的格式也是基本不变的。
- package client;
- import myHelloWorld.HelloWorldPrx;
- import myHelloWorld.HelloWorldPrxHelper;
- public class Client {
- public static void main(String[] args)
- {
- int status = 0;
- // Communicator实例
- Ice.Communicator ic = null;
- try
- {
- // 调用Ice.Util.Initialize()初始化Ice run time
- ic = Ice.Util.initialize(args);
- // 根据servant的名称以及服务器ip、端口获取远程服务代理
- Ice.ObjectPrx base = ic.stringToProxy("SimplePrinter:default -p 10000");
- // 将上面的代理向下转换成一个Printer接口的代理
- HelloWorldPrx helloWorld = HelloWorldPrxHelper.checkedCast(base);
- // 如果转换成功
- if (helloWorld == null)
- {
- throw new Error("Invalid proxy");
- }
- // 调用这个代理,将字符串传给它
- helloWorld.say("bar");
- } catch (Ice.LocalException e)
- {
- e.printStackTrace();
- status = 1;
- } catch (Exception e)
- {
- e.printStackTrace();
- status = 1;
- } finally
- {
- if (ic != null)
- {
- ic.destroy();
- }
- }
- System.exit(status);
- }
- }
六、运行
先运行服务器,服务器线程一直运行等待,如下:
- 初始化ice run time...
- 创建对象适配器,监听端口10000...
- 为接口创建servant...
- 对象适配器加入servant...
- 激活适配器,服务器等待处理请求...
运行了客户端后,显示如下:
- 初始化ice run time...
- 创建对象适配器,监听端口10000...
- 为接口创建servant...
- 对象适配器加入servant...
- 激活适配器,服务器等待处理请求...
- Hello World! the string s is bar
七、小结
以上的代码是同一台电脑之间调用,如果需要跨服务器之间调用,或者无论其他什么语言的客户端调用,只需要获取远程服务代理的时候加上ip即可。default默认采取tcp协议,所以下边的代码其实等同于上边我们调用本地机器的代码。
- Ice.ObjectPrx base = ic.stringToProxy("SimplePrinter:tcp -h 127.0.0.1 -p 10000");
上边是最简单的ice调用,它的优势是:在我们编写服务端客户端的时候,不需要考虑调用方是什么语言编写的,只需要按照我们当前使用语言的书写习惯去完成我们自己一端的代码即可,并且服务器客户端之间可以通过结构体(对象)的方式进行直接调用,更符合我们的日常变成习惯。
下一节我会把如何ice amd调用的原理以及如何通过java语言编写ice服务端、客户端的代码分享出来,后边可能还会有如何通过ice建立长连接,实现服务器客户端的互相调用。
ZEROC ICE 跨平台间程序调用 java版的更多相关文章
- 应用程序初次运行数据库配置小程序(Java版)
应用程序初始化数据库配置小程序 之前写过一个Java版的信息管理系统,但部署系统的时候还需要手动的去配置数据库和导入一些初始化的数据才能让系统运行起来,所以我在想是不是可以写一个小程序在系统初次运行的 ...
- 0917 词法分析程序(java版)
1.运行结果: 2.源代码: package 词法分析;import java.util.Scanner;public class fenxi {public static void main(Str ...
- 微信退款和支付宝退款接口调用(java版)
项目中需要使用到微信和支付宝的退款功能,在这两天研究了一下这两个平台的退款,有很多坑,在开发中需要留意 1.微信退款接口 相对来说我感觉微信的退款接口还是比较好调用的,直接发送httppost请求即可 ...
- Delphi XE7的安卓程序如何调用JAVA的JAR,使用JAVA的类?
本文使用工具和全部源码下载: http://download.csdn.net/detail/sunylat/8190765 为什么我们要在Delphi XE7的安卓程序调用JAVA的JAR,使用JA ...
- C++ 跨语言调用 Java
C++ 跨语言调用 Java Java JDK 提供了 JNI 接口供 C/C++ 程序调用 Java 编译后的类与方法,主要依赖于头文件(jni.h) 和 动态库(jvm.so/jvm.dll),由 ...
- C调用java JNI_CreateJavaVM只能调用成功一次
https://bbs.csdn.net/topics/392264971 再使用c语言调用java代码的时候,选择使用JNI,根据网上的提示已经能够正常跑了,int mask_name( char* ...
- 微信小程序支付 java
原文:https://blog.csdn.net/zhourenfei17/article/details/77765585 话不多说,直接开撸. 支付流程步骤: 1)首先调用wx.login方法获取 ...
- Ubuntu16.04下ZeroC ICE的安装与使用示例(Qt C++ 和 Java)
项目需求:在Ubuntu16.04系统下安装并使用ICEgrid 3.7进行c++和Java Springboot开发环境的通信,下面逐一介绍各个步骤的详解: 一:Ice Lib的安装 参考官网地址: ...
- 开发zeroc ice应用入门(java开发ice应用,python开发ice应用,java与python结合开发ice服务)
ice作为一种rpc框架,为主流平台设计,包括Windows和Linux,支持广泛的语言,包括C++,Java,C#(和其他.Net的语言,例如Visual Basic),Python,Ruby,PH ...
随机推荐
- 用canvas的arc绘制时钟
在页面上加入canvas标签: <body> <canvas id="c1" width="600px" height="600px ...
- 微信小程序开发入门
微信小程序 首先说下结构吧,看看小程序到底长什么样子 这是一个微信提供的自己的开发工具,相当于xcode吧,由此也可以看出腾讯的野心并不小啊,左边的就是编辑调试什么的,往右就是一个模拟器,你可以选择i ...
- c风格字符串,字符串字面值,c++字符串
C风格字符串:本质上就是以空字符null为结束符的数组 可以简单的理解为:有'\0'的是c风格字符串,无'\0'的是普通字符数组 字符串字面值:是一串常量字符,字符串字面值常量用双引号括起来的零个或多 ...
- smarty模板基础3 *缓存数据*
缓存数据,这个并不是暂存的缓存,而是写入了内存的缓存 通过一个例子来书写:缓存数据 一.书写php和html页面的基本功能 既然是用smarty模板,那么前端和后端要分开写了 (1)php页面 < ...
- Django之admin
django amdin是django提供的一个后台管理页面,改管理页面提供完善的html和css,使得你在通过Model创建完数据库表之后, 就可以对数据进行增删改查,而使用django admin ...
- MySQL学习分享-->查询-->查询的分类
MySQL的查询可以分为交叉联接.内联接.外联接.自然联接.straight_join 下面对于查询的学习,会用到以下四张表: create table t_commodity_type( `id` ...
- ajax基础部分
今天讲了ajax的组成及使用方法:首先我们看看一个简单的ajax的例子: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transition ...
- C#-MVC开发微信应用(2)--OAuth2.0网页授权
微信公众平台最近新推出微信认证,认证后可以获得高级接口权限,其中一个是OAuth2.0网页授权,很多朋友在使用这个的时候失败了或者无法理解其内容,希望我出个教程详细讲解一下,于是便有了这篇文章. 一. ...
- C++类对象大小的计算
(一)常规类大小计算 C++类对象计算需要考虑很多东西,如成员变量大小,内存对齐,是否有虚函数,是否有虚继承等.接下来,我将对此举例说明. 以下内存测试环境为Win7+VS2012,操作系统为32位 ...
- Linux系统常用命令总结
1. 最关键的命令 manecho 2. 目录文件操作命令 ls: 查看目录下的文件信息或文件信息dir:pwd: 打印当前路径cd:改变路径mkdir:创建路径rmdir:删除路径cp:拷贝文件或目 ...