前言:

  本来建博客是为了和大家分享一些前端的开发经验和心得呢,但是阴差阳错,第一篇技术博客确实关于跨平台,跨语言服务端调用的解决方案---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. Linux内核时间管理(二)——jiffies与jiffies_64释疑

    Linux内核中定义了jiffies变量来记录从系统启动到当前时刻系统时钟所产生的tick数.jiffies变量是一个无符号整型数值,即unsigned long类型.它的声明如下(在 include ...

  2. mybatis系列笔记(3)---SqlMapConfig.xml解析

    SqlMapConfig.xml SqlMapConfig.xml是Mybatis的全局配置参数,关于他的具体用的有专门的MyBatis - API文档,这里面讲的非常清楚,所以我这里就挑几个讲下: ...

  3. java中map集合的迭代

    import java.util.HashMap; import java.util.Iterator; import java.util.Map; public class TestMap { pu ...

  4. Javascript把数据从一个页面的层传递到另一个页面层里面

    背景:昨天头脑发热投了某一家国企的计算机类岗位(说是有前端岗位),通过找同学内推,虽然也笔试了一大堆题目(行测题,计算机网络,http协议,英译汉,古诗文默写,自己把品质排序并且进行200字以上的阐述 ...

  5. GCD浅析

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Helvetica; color: #000000 } span.s1 { } 1.关于GCD ...

  6. Java垃圾回收学习笔记

    通常来说,要写Java代码,你基本上都没必要听说垃圾回收这个概念的.这不,对于已经写了5年多Java代码的我来说,我还没有哪次经历说是需要使用垃圾回收方面的知识来解决问题的.但是,我依然督促自己花了几 ...

  7. c/c++重定向输入输出

    #define Local #include <iostream> #include <cstdio> //#include <stdio.h> using nam ...

  8. html中submit和button的区别(总结) [ 转自欣步同学 ]

    html中submit和button的区别(总结) submit是button的一个特例,也是button的一种,它把提交这个动作自动集成了. 如果表单在点击提交按钮后需要用JS进行处理(包括输入验证 ...

  9. 基于GDAL的遥感影像显示(C#版)

    基于GDAL的遥感影像显示(C#版) - 菜菜的专栏 - 博客频道 - CSDN.NET  http://blog.csdn.net/RSyaoxin/article/details/9220735

  10. 解决 Linux error while loading shared libraries: cannot open shared object file: No such file or directory

    安装最新版本Emqtt,参照官方文档安装后,执行报错: Linux error while loading shared libraries libsctp.so.1: cannot open sha ...