ICE ZEROC文档翻译 (二)(Java)

来源:互联网 发布:阿里云服务器黑洞 编辑:程序博客网 时间:2024/06/06 21:38

Hello World Application

Hello World 小程序

Writing a Slice Definition

1. 写个Slice 文件

The first step in writing any Ice application is to write a Slice definition containing the interfaces that are used by the application. For our minimal printing application, we write the following Slice definition:
第一步写任何ICE应用就是先写个Slice 定义文件 包括应用要用到的接口.
对我们的小程序来说 我们这么写

module Demo{    interface Printer    {        void printString(string s);    }}

//看了别人的博客 自己写了第一行的目录,这个好像是在当前目录下生成com….目录 我是用命令行生成的 血崩
感觉对Java 不是怎么友好

[["java:package:com.ygdxd.generated"]]module Demo{    interface Printer    {        void printString(string s);    }}

We save this text in a file called Printer.ice.
保持成Printer.ice 文件

Our Slice definitions consist of the module Demo containing a single interface called Printer. For now, the interface is very simple and provides only a single operation, called printString. The printString operation accepts a string as its sole input parameter; the text of that string is what appears on the (possibly remote) printer.
我们定义的Slice中包含modual:Demo 包括一个叫Printer接口.现在,这个接口非常简单 并且只提供了一个叫做 printString 功能 .printString 接口接受一个String 的参数 这个String的值是可能远端printer传过来的.

Writing an Ice Application with Java

Java 端

Compiling a Slice Definition for Java

编译Slice 需要先安装https://zeroc.com/downloads/ice

The first step in creating our Java application is to compile our Slice definition to generate Java proxies and skeletons. You can compile the definition as follows:
创建Java应用的第一步是编译Slice文件来得到Java 代理和结构文件,你执行下面命令:

$ mkdir generated //创建目录$ slice2java --output-dir generated Printer.ice //generated 这个是当前目录 

The –output-dir option instructs the compiler to place the generated files into the generated directory. This avoids cluttering the working directory with the generated files. The slice2java compiler produces a number of Java source files from this definition. The exact contents of these files do not concern us for now — they contain the generated code that corresponds to the Printer interface we defined in Printer.ice.

–output-dir命令指定编译的地址生成文件到generated目录.这个避免了杂乱的工作目录和生成文件混在一起.slice2java命令 编译产生了大量的Java源文件从Slice中.这些文件的详细内容我们现在还不用关心–他们(生成的文件)包含的代码和Printer.ice定义的接口相对应.

Writing and Compiling a Server in Java

Server端

implement our Printer interface, we must create a servant class. By convention, a servant class uses the name of its interface with an I-suffix, so our servant class is called PrinterI and placed into a source file PrinterI.java:
要实现接口必须先创建一个服务类.按照惯例,1个服务类用它接口的名字加一个I在后面 所以我们创建一个PrinterI.java

public class PrinterI implements Demo.Printer{    public void printString(String s, com.zeroc.Ice.Current current)    {        System.out.println(s);    }}

The PrinterI class implements the interface Printer, which is generated by the slice2java compiler. The interface defines a printString method that accepts a string for the printer to print and a parameter of type Current. (For now we will ignore the Current parameter.) Our implementation of the printString method simply writes its argument to the terminal.
PrinterI.class 实现slice2java命令生成的Printer接口.这个接口定义了一个printString方法接受一个String 参数和一个Current.现在我们先忽略Current
我们实现的printString 方法先简单的打印一下他的参数在控制台.

The remainder of the server code is in a source file called Server.java, shown in full here:
下面是Server.class 代码

public class Server{    public static void main(String[] args) throws Exception    {        try(com.zeroc.Ice.Communicator communicator = com.zeroc.Ice.Util.initialize(args))        {            com.zeroc.Ice.ObjectAdapter adapter = communicator.createObjectAdapterWithEndpoints("SimplePrinterAdapter", "default -p 10000");            com.zeroc.Ice.Object object = new PrinterI();            adapter.add(object, com.zeroc.Ice.Util.stringToIdentity("SimplePrinter"));            adapter.activate();            communicator.waitForShutdown();        }    }}

The main method is declared to throw Exception. If the code throws an exception, it will be handled by the JVM which typically prints out the exception and then returns failure to the operating system. The body of main contains a try-with-resources block in which we place all the server code.
main方法被指定抛出Exception,如果代码抛异常,它会被JVM捕获然后打印错误并返回失败给系统.main方法包含一个try-with-resources块包含我们的所有代码.

The Communicator object implements java.lang.AutoCloseable, which allows us to use the try-with-resources statement for the initialization of the Communicator object. This ensures the communicator destroy method is called when the try block goes out of scope. Doing this is essential in order to correctly finalize the Ice run time.
Communicator实现了java.lang.AutoCloseable 允许我们去用try-with-resources 来加载Communicator对象.这确保了communicator的销毁方法会执行当超出范围(报错或关闭?).这是为了确保Ice运行的时候程序正确的运行.

Failure to call destroy on the communicator before the program exits results in undefined behavior.
在程序退出前没有执行必要的销毁方法会出现未知的情况.

The body of our try block contains the actual server code.
try语句块包括下面server代码

  1. We initialize the Ice run time by calling com.zeroc.Ice.Util.initialize. (We pass args to this call because the server may have command-line arguments that are of interest to the run time; for this example, the server does not require any command-line arguments.) The call to initialize returns a Communicator reference, which is the main object in the Ice run time.
    我们加载Ice 运行通过调用com.zeroc.Ice.Util.initialize 方法 (我们通过args参数去调用因为server 可能有命令行的参数 要配置运行参数; 举个例子,先不用设置参数) 调用初始化后会返回一个在ICE运行的当前的实例Communicator 实例,
  2. We create an object adapter by calling createObjectAdapterWithEndpoints on the Communicator instance. The arguments we pass are “SimplePrinterAdapter” (which is the name of the adapter) and “default -p 10000”, which instructs the adapter to listen for incoming requests using the default protocol (TCP/IP) at port number 10000.
    我们创建一个适配器 通过调用createObjectAdapterWithEndpoints 在Communicator实例上.设置参数”SimplePrinterAdapter”(适配器的名字) and “default -p 10000” (适配器监听的请求 在TCP10000端口的收到的请求)
  3. At this point, the server-side run time is initialized and we create a servant for our Printer interface by instantiating a PrinterI object
    此时,服务端已经加载并且我们要创建一个服务类实例化PrinterI对象一个来实现我们的Printer 接口.
  4. We inform the object adapter of the presence of a new servant by calling add on the adapter; the arguments to add are the servant we have just instantiated, plus an identifier. In this case, the string “SimplePrinter” is the name of the Ice object. (If we had multiple printers, each would have a different name or, more correctly, a different object identity.)
    我们调用适配器的add方法通知一个新的服务类的存在的适配对象;参数是我们
    刚刚实例化的服务类再加上一个标识符.
  5. Finally, we call waitForShutdown. This call suspends the calling thread until the server implementation terminates, either by making a call to shut down the run time, or in response to a signal. (For now, we will simply interrupt the server on the command line when we no longer need it.)
    最后,我们调用waitForShutdown方法.这个方法调用后会挂起这个线程直到server服务的终止,或者被一个终止命令/方法终止,否则就会一直等到客户端的信号.(但是现在,我们只是简单地在命令行上中断服务器当我们不再需要它)
    Note that, even though there is quite a bit of code here, that code is essentially the same for all servers. You can put that code into a helper class and, thereafter, will not have to bother with it again. (Ice provides such a helper class, called Application.) As far as actual application code is concerned, the server contains only a few lines: seven lines for the definition of the PrinterI class, plus three lines to instantiate a PrinterI object and register it with the object adapter.
    请注意,虽然这里只有一点代码在上面,但是几乎所有的服务器代码都和上面的差不多.你可以复制上面的代码到帮助类,此后,就不再需要重复写(烦恼)了.(Ice 提供了一个叫Application的帮助类) 就实际应用代码而言,这个服务类包括下面几点:几行定义PrinterI类的代码,加上3行代码实例化PrinterI 对象和注册它到对象适配类中.

We can compile the server code as follows:
编译代码

$ mkdir classes$ javac -d classes -classpath classes:$ICE_HOME/lib/ice.jar Server.java PrinterI.java generated/Demo/*.java

This compiles both our application code and the code that was generated by the Slice compiler. We assume that the ICE_HOME environment variable is set to the top-level directory containing the Ice run time. (For example, if you have installed Ice in /opt/Ice, set ICE_HOME to that path.) Note that Ice for Java uses Gradle to control building of source code. (Gradle is similar to make, but more flexible for Java applications.) You can have a look at the demo code that ships with Ice to see how to use this tool.
这个命令同时编译Slice文件生成的代码和应用代码.我们假定设置最高的目录为ICE_HOME的环境变量在运行ICE中.(举个例子,你下载ICE到/opt/ice目录,设置ICE_HOME环境变量到当前目录.)注意,ICE用Gradle来控制编译源代码对JAVA程序.(Gradle能代替make,但是对Java程序能够更灵活)你可以查看DEMO代码附带ice来看如何使用这个工具

Writing and Compiling a Client in Java

编写编译Client

The client code, in Client.java, looks very similar to the server. Here it is in full:
Client.java 几乎和server一样 这里是全部代码

public class Client{    public static void main(String[] args)    {        try(com.zeroc.Ice.Communicator communicator = com.zeroc.Ice.Util.initialize(args))        {            com.zeroc.Ice.ObjectPrx base = communicator.stringToProxy("SimplePrinter:default -p 10000");            Demo.PrinterPrx printer = Demo.PrinterPrx.checkedCast(base);            if(printer == null)            {                throw new Error("Invalid proxy");            }            printer.printString("Hello World!");        }    }}

Note that the overall code layout is the same as for the server: we use the same try and catch blocks to deal with errors. The code in the try block does the following:
注意 总体的代码格式和server差不多:我们使用同样相同的try and catch blocks代码块来处理错误.try代码块的详解如下

  1. As for the server, we initialize the Ice run time by calling com.zeroc.Ice.Util.initialize within the Java try-with-resources statement.
    至于server,我们通过调用com.zeroc.Ice.Util.initialize放在try-with-resources中来加载Ice.
  2. The next step is to obtain a proxy for the remote printer. We create a proxy by calling stringToProxy on the communicator, with the string “SimplePrinter:default -p 10000”. Note that the string contains the object identity and the port number that were used by the server. (Obviously, hard-coding object identities and port numbers into our applications is a bad idea, but it will do for now; we will see more architecturally sound ways of doing this when we discuss IceGrid.)
    下一步是创建一个代理类来给远程的printer.我们创建一个代理类通过调用communicator的stringToProxy方法,带上String参数(“SimplePrinter:default -p 10000”).注意 字符串包含对象的Id 和端口号 (server暴露的).(显然,硬编码对象的ID和端口号在我们的应用中不是一好的方式,但是 我们现在先这么简单地做,我们会发现更多结构合理的方式当我们讨论 IceGrid)
  3. The proxy returned by stringToProxy is of type com.zeroc.Ice.ObjectPrx, which is at the root of the inheritance tree for interfaces and classes. But to actually talk to our printer, we need a proxy for a Printer interface, not an Object interface. To do this, we need to do a down-cast by calling PrinterPrx.checkedCast. A checked cast sends a message to the server, effectively asking “is this a proxy for a Printer interface?” If so, the call returns a proxy of type Demo::Printer; otherwise, if the proxy denotes an interface of some other type, the call returns null.
    stringToProxy返回的代理类型是com.zeroc.Ice.ObjectPrx,是接口和子类的继承树的根节点.但是实际上对我们的printer来说,我们需要一个代理类来实现一个Printer接口,不是一个对象接口.所以,我们不得不做一个降级(根->子?)通过调用PrinterPrx.checkedCast.发送一个检查类型消息给server,有效快捷的问”是否是Printer接口的代理类”,如果是那样,调用地方法返回一个PrinterPrx类型;否则,如果代理对象是别的类型的,返回null.
  4. We test that the down-cast succeeded and, if not, throw an error message that terminates the client.
    我们假设降级是成功的,如果不是,抛一个错误的信息给客户端命令控制台.
  5. We now have a live proxy in our address space and can call the printString method, passing it the time-honored “Hello World!” string. The server prints that string on its terminal.
    我们现在有活生生的一个代理类在我们的地址空间中并且调用printString方法,
    并且传一个”Hello World!”参数,服务器端打印字符串在它的控制台.
    Compiling the client looks much the same as for the server:
    服务端编译和客户端一样

Running Client and Server in Java

在java上运行Client和Server

To run client and server, we first start the server in a separate window:
先开server

$ java Server

The client runs and exits without producing any output; however, in the server window, we see the “Hello World!” that is produced by the printer. To get rid of the server, we interrupt it on the command line for now. (We will see cleaner ways to terminate a server in our discussion of the Application class.)
client端执行和退出不会产生任何提示;然而,在server的界面,我们看到”Hello World!” 由printer产生.离开server,我们现在关闭命令行.(我们可以通过更清楚地方式来终止server在我们讨论的Application.class中)

if anything goes wrong, the client will print an error message. For example, if we run the client without having first started the server, we get something like the following
如果有任何错误,客户端会打印一个错误信息.举个例子,如果我们在server之前先打开client,我们会得到下面类似信息

com.zeroc.Ice.ConnectionRefusedException       error = 0    at ...    at Client.run(Client.java:65)Caused by: java.net.ConnectException: Connection refused         ...

Note that, to successfully run client and server, your CLASSPATH must include the Ice library and the classes directory, for example:
注意,想要成功地运行client和server,你的根目录必须包含Ice依赖和类目录,举个例子:

$ export CLASSPATH=$CLASSPATH:./classes:$ICE_HOME/lib/ice.jar

Please have a look at the demo applications that ship with Ice for the details for your platform.
请看一看demo的细节根据你的需求 附带ice

本人水平有限,望谅解.

未经允许,请勿转载等.