前言:

  本来建博客是为了和大家分享一些前端的开发经验和心得呢,但是阴差阳错,第一篇技术博客确实关于跨平台,跨语言服务端调用的解决方案---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版的更多相关文章

  1. 应用程序初次运行数据库配置小程序(Java版)

    应用程序初始化数据库配置小程序 之前写过一个Java版的信息管理系统,但部署系统的时候还需要手动的去配置数据库和导入一些初始化的数据才能让系统运行起来,所以我在想是不是可以写一个小程序在系统初次运行的 ...

  2. 0917 词法分析程序(java版)

    1.运行结果: 2.源代码: package 词法分析;import java.util.Scanner;public class fenxi {public static void main(Str ...

  3. 微信退款和支付宝退款接口调用(java版)

    项目中需要使用到微信和支付宝的退款功能,在这两天研究了一下这两个平台的退款,有很多坑,在开发中需要留意 1.微信退款接口 相对来说我感觉微信的退款接口还是比较好调用的,直接发送httppost请求即可 ...

  4. Delphi XE7的安卓程序如何调用JAVA的JAR,使用JAVA的类?

    本文使用工具和全部源码下载: http://download.csdn.net/detail/sunylat/8190765 为什么我们要在Delphi XE7的安卓程序调用JAVA的JAR,使用JA ...

  5. C++ 跨语言调用 Java

    C++ 跨语言调用 Java Java JDK 提供了 JNI 接口供 C/C++ 程序调用 Java 编译后的类与方法,主要依赖于头文件(jni.h) 和 动态库(jvm.so/jvm.dll),由 ...

  6. C调用java JNI_CreateJavaVM只能调用成功一次

    https://bbs.csdn.net/topics/392264971 再使用c语言调用java代码的时候,选择使用JNI,根据网上的提示已经能够正常跑了,int mask_name( char* ...

  7. 微信小程序支付 java

    原文:https://blog.csdn.net/zhourenfei17/article/details/77765585 话不多说,直接开撸. 支付流程步骤: 1)首先调用wx.login方法获取 ...

  8. Ubuntu16.04下ZeroC ICE的安装与使用示例(Qt C++ 和 Java)

    项目需求:在Ubuntu16.04系统下安装并使用ICEgrid 3.7进行c++和Java Springboot开发环境的通信,下面逐一介绍各个步骤的详解: 一:Ice Lib的安装 参考官网地址: ...

  9. 开发zeroc ice应用入门(java开发ice应用,python开发ice应用,java与python结合开发ice服务)

    ice作为一种rpc框架,为主流平台设计,包括Windows和Linux,支持广泛的语言,包括C++,Java,C#(和其他.Net的语言,例如Visual Basic),Python,Ruby,PH ...

随机推荐

  1. 工具使用——MATLAB基本调试方法

    作者:桂. 时间:2017-02-28  07:06:30 链接:http://www.cnblogs.com/xingshansi/articles/6477185.html 声明:转载请注明出处, ...

  2. 关于RunLoop

    首先我们要先认识一下这个RunLoop; NSRunLoop是Cocoa框架中的类,与之的Core Fundation 中CFRunLoopRef类. 这两者的区别是,前者不是线程安全的,而后者是线程 ...

  3. iOS视频编辑SDK

    IOS视频编辑SDK接入说明 一.名词解释 分辨率:用于计算机视频处理的图像,以水平和垂直方向上所能显示的像素数来表示分辨率.常见视频分辨率的有1080P即1920x1080,720P即1080x72 ...

  4. Kubernetes运维生态-Heapster分析

    Heapster在Kubernetes的运维生态中如下:集群的容器的监控数据收敛汇聚层 heapster1.0版本后内部分为event和metric两个进程,可制作为两个docker镜像部署为两个独立 ...

  5. Oracle 数据库启用归档

    一.关闭数据库 二.启动数据库到mount状态 三.启用或停止归档模式 启用 停用 四.开启数据库并查看归档模式 参考文档:http://blog.csdn.net/feifei_86/article ...

  6. Struts2学习笔记③

    今天把这两天看书体会的Struts的运行原理记录一下:其实Struts官方提供了一张图可以视为景点,几乎每一个将Struts的课程都会使用: 上面的图里面的struts核心过滤器已经更换为Struts ...

  7. wemall app商城源码中基于JAVA的绑定和处理fragments和viewpager之间的逻辑关系代码

    wemall doraemon是Android客户端程序,服务端采用wemall微信商城,不对原商城做任何修改,只需要在原商城目录下上传接口文件即可完成服务端的配置,客户端可随意定制修改.本文分享其中 ...

  8. 1583: [Usaco2009 Mar]Moon Mooing 哞哞叫

    1583: [Usaco2009 Mar]Moon Mooing 哞哞叫 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 244  Solved: 126 ...

  9. C++中的动态链接库

    一,动态链接库的基本概念 1.DLL(Dynamic Linker Library)的概念 可以把DLL看做是一个仓库,它提供了一些可以直接拿来用的变量,函数或者类(但是不建议从DLL中获取变量),在 ...

  10. php流程管理练习

    今天我们做一个流程管理: 1.流程管理的用法是什么样的? 2.怎么发起想要的流程? 3.审批的人要是怎么审批通过? 4.流程审核是不是要挨个走过? 一. 做这个流程管理肯定要有数据库: 二.数据库结束 ...