系统安装ice3.4.1,并配置环境变量;

定义slice文件

1
2
3
4
5
6
7
8
9
10
[[ "java:package:com.hhly.tel.ice"]]
module book {
   interface OnlineBook {
       void bookTick(string name,double price,string content);
   };
   
   interface SMSService {
       void sendSMS(string name,double price,string content);
   };
};

这表示有2个接口,一个OnlineBook,一个SMSService,都位于com.hhly.tel.ice.book下面。

生成JAVA类

使用slice2java xx.ice生成

然后将生成的类复制到工程中

上图中圈红的都是ice生成的类。

实现我们自己的逻辑

如上图的service下面,是OnlineBook和SMSService的实现,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package com.hhly.tel.ice.book.service;
import Ice.Communicator;
import Ice.Current;
import Ice.ObjectAdapter;
import IceBox.Service;
import com.hhly.tel.ice.book._OnlineBookDisp;
import org.apache.log4j.Logger;
/**
* @Author j.tommy
* @Date 2016/6/19 0019 上午 4:08
*/
public class ICEBookService extends _OnlineBookDisp implements Service{
 public static final Logger log = Logger.getLogger(ICEBookService.class);
 private ObjectAdapter _adapter;
 @Override
 public void bookTick(String name, double price, String content, Current __current) {
     log.info("Call bookTick()...params->[name=" + name + ",price=" + price + ",content=" + content + "].");
 }
 @Override
 public void start(String name, Communicator communicator, String[] strings) {
     // 创建objectAdapter,这里和service同名
     _adapter = communicator.createObjectAdapter(name);
     // 传Serant并激活
     Ice.Object object = this;
     _adapter.add(object,communicator.stringToIdentity(name));
     _adapter.activate();
     log.info(name + " started.");
 }
 @Override
 public void stop() {
     log.info(this._adapter.getName() + " stoped.");
     _adapter.destroy();
 }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package com.hhly.tel.ice.book.service;
import Ice.Communicator;
import Ice.Current;
import Ice.ObjectAdapter;
import IceBox.Service;
import com.hhly.tel.ice.book._SMSServiceDisp;
import org.apache.log4j.Logger;
/**
* @Author j.tommy
* @Date 2016/6/19 0019 上午 4:08
*/
public class ICESMSService extends _SMSServiceDisp implements Service{
    public static final Logger log = Logger.getLogger(ICESMSService.class);
    private ObjectAdapter _adapter;
    @Override
    public void start(String name, Communicator communicator, String[] strings) {
        // 创建objectAdapter,这里和service同名
        _adapter = communicator.createObjectAdapter(name);
        // 传Serant并激活
        Ice.Object object = this;
        _adapter.add(object,communicator.stringToIdentity(name));
        _adapter.activate();
        log.info(name + " started.");
    }
    @Override
    public void stop() {
        log.info(this._adapter.getName() + " stoped.");
        _adapter.destroy();
    }
    @Override
    public void sendSMS(String name, double price, String content, Current __current) {
        log.info("Call sendSMS()...params->[name=" + name + ",price=" + price + ",content=" + content + "].");
    }
}

icebox的配置文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#server properties
# icebox实例的名字
IceBox.InstanceName=MyAppIceBox 1
# =1表示所有的服务使用Icebox中的配置
IceBox.InheritProperties=1
# =1会在icebox启动完毕后打印MyAppIceBox 1 ready
IceBox.PrintServicesReady=MyAppIceBox 1
#IceBox的管理组件,使之能够被远程访问,默认关闭,下面将其绑定到本地9999端口
IceBox.ServiceManager.Endpoints=tcp -p 8989 -h localhost
#performance properties
Ice.ThreadPool.Server.Size=4
Ice.ThreadPool.Server.SizeMax=100
Ice.ThreadPool.Server.SizeWarn=10
Ice.ThreadPool.Client.Size=4
Ice.ThreadPool.Client.SizeMax=100
Ice.ThreadPool.Client.SizeWarn=40
#for system stronger
Ice.ACM.Client=300
Ice.ACM.Server=300
#log and trace
#表明日志存放在日志文件中,否则会打印到控制台。
#Ice.LogFile=iceserv.log
Ice.PrintStackTraces=1
Ice.Trace.Retry=2
Ice.Trace.Network=2
Ice.Trace.ThreadPool=1
Ice.Trace.Locator=2
Ice.Warn.Connections=1
Ice.Warn.Dispatch=1
Ice.Warn.Endpoints=1
#service defined begin
IceBox.Service.OnlineBook=com.hhly.tel.ice.book.service.ICEBookService prop1=1 prop2=2 prop3=3
IceBox.Service.SMSService=com.hhly.tel.ice.book.service.ICESMSService
OnlineBook.Endpoints=tcp -p 9000 -h localhost
SMSService.Endpoints=tcp -p 9001 -h localhost
#service defined end
#server load order
IceBox.LoadOrder=OnlineBook,SMSService
#service share communicator
IceBox.UseSharedCommunicator.OnlineBook=1
IceBox.UseSharedCommunicator.SMSService=1

IceBox.Service.name=entry_point [–key=value] [args]
各个参数的定义:
name定义了service的名字,如上面定了2个Service,一个OnlineBook,一个SMSService.
entry_point是service的完整类名
[–key=value]将会被作为property属性,用于构造该服务的communicator,用来更加精确的控制每个Ice服务的性能调优,这里也可以使用–Ice.Config=xxx.cfg的方式从具体的配置文件加载参数。
IceBox.InheritProperties=1,让所有的ice服务都使用IceBox的配置属性。
[args]作为参数传入start()方法的args参数,作为服务端启动初始化参数。

Ice.MessageSizeMax:做大消息包的字节数
Ice.Trace.Network=1,开启网络事件相关的日志追踪
Ice.Trace.ThreadPool=1,开启线程池事件的日志追踪
Ice.Trace.Locator=1,开启Locator对象的日志追踪

IceBox.UseShardedCommunicator.serviceName=1,实现服务本地调用的优化。如上面的OnlineBook和SMSService,都部署在同一个IceBox中,定义他们使用同一个Communicator对象,实现本地调用的优化。

IceBox.LoadOrder=serv1,serv2,serv3,指定服务的加载顺序,如上面的OnlineBook和SMSService。

启动服务,并启动

1
2
3
4
5
6
7
8
9
10
11
package com.hhly.tel.ice.book.client;
/**
 * @Author j.tommy
 * @Date 2016/6/19 0019 上午 4:33
 */
public class Server {
   public static void main(String[] args) {
      IceBox.Server server = new IceBox.Server();
      server.main(new String[]{"--Ice.Config=icebox.properties"});
   }
}

编写客户端并启动

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
package com.hhly.tel.ice.book.client;
import com.hhly.tel.ice.book.*;
/**
* @Author j.tommy
* @Date 2016/6/19 0019 上午 4:27
*/
public class Client {
   public static void main(String[] args) {
       // 调用OnlineBook接口
        bookTick(args);
        // 调用SMSService接口
        sendSMS(args);
    }
    private static void bookTick(String[] args) {
        int status = 0;
        Ice.Communicator ic = null;
        try {
            ic = Ice.Util.initialize(args);
            Ice.ObjectPrx base = ic.stringToProxy("OnlineBook:default -p 9000");
            OnlineBookPrx onlineBookPrx = OnlineBookPrxHelper.checkedCast(base);
            if (onlineBookPrx == null) {
                throw new Error("Invalid proxy");
            }
            onlineBookPrx.bookTick("ICE权威指南",59,"这是一本介绍ICE的书籍。");
        } catch (Error error) {
            error.printStackTrace();
            status = 1;
        } finally {
            if (ic != null) {
                ic.destroy();
            }
//            System.exit(status);
        }
    }
    private static void sendSMS(String[] args) {
        int status = 0;
        Ice.Communicator ic = null;
        try {
            ic = Ice.Util.initialize(args);
            Ice.ObjectPrx base = ic.stringToProxy("SMSService:default -p 9001");
            SMSServicePrx smsServicePrx = SMSServicePrxHelper.checkedCast(base);
            if (smsServicePrx == null) {
                throw new Error("Invalid proxy");
            }
            smsServicePrx.sendSMS("ICE权威指南",59,"这是一本介绍ICE的书籍。");
        } catch (Error error) {
            error.printStackTrace();
            status = 1;
        } finally {
            if (ic != null) {
                ic.destroy();
            }
            System.exit(status);
        }
    }
}

ICE Service之间的调用

ICESMSService的实现方法修改如下:

@Override
public void sendSMS(String name, double price, String content, Current __current) {
    if (name.startsWith("book")) {
        Ice.ObjectPrx base = _adapter.getCommunicator().stringToProxy("OnlineBook");
        OnlineBookPrx onlineBookPrx = OnlineBookPrxHelper.checkedCast(base);
        if (null != onlineBookPrx) {
            onlineBookPrx.bookTick(name,price,content);
            log.info("通过短信购买图书!...params->[name=" + name + ",price=" + price + ",content=" + content + "].");
        }
         else {
             throw new Error("Can't find OnlinkBook Service.");
         }
     }
     else {
         log.info("发送短信成功...params->[name=" + name + ",price=" + price + ",content=" + content + "].");
     }
 }

上面的代码表明:如果name以book开头,则内部调用OnlineBookService购买图书。否则就是发送短信。

试验:
客户端代码:

private static void sendSMS(String name,double price,String content,String[] args) {
    int status = 0;
    Ice.Communicator ic = null;
    try {
        ic = Ice.Util.initialize(args);
        Ice.ObjectPrx base = ic.stringToProxy("SMSService:default -p 9001");
        SMSServicePrx smsServicePrx = SMSServicePrxHelper.checkedCast(base);
        if (smsServicePrx == null) {
            throw new Error("Invalid proxy");
         }
         smsServicePrx.sendSMS(name,price,content);
     } catch (Error error) {
         error.printStackTrace();
         status = 1;
     } finally {
         if (ic != null) {
             ic.destroy();
         }
//            System.exit(status);
     }
 }
public static void main(String[] args) {
    // 调用OnlineBook接口
    bookTick(args);
    System.out.println("bookTick(args) Finished");
    // 调用SMSService接口
    sendSMS("book ICE权威指南",59,"这是一本介绍ICE的书籍。",args);
    System.out.println("sendSMS() Finished");
    // 在SMSService中调用OnlineBookService,演示ICE服务之间的调用
    sendSMS("发送短信",59,"这是一本介绍ICE的书籍。",args);
     System.out.println("Send Message Finished.");
 }