ICE java实现服务双向调用

目录

一 前言

二 实现

1、目录结构

2、公共代码

3、java实现

4、spring实现(spring启动ice)

三 项目git  https://github.com/HandsomeMars/springboot-ice-demo


一 前言

1、基于上篇ice简单使用,本篇文章讲讲如何实现客户端与服务端之间双向调用

2、本文列举两种实现:

  • java main方法调用
  • 结合spring IOC容器管理

二 实现

1、目录结构

├─main
│  ├─java
│  │  │  .depend
│  │  │
│  │  ├─com
│  │  │  └─zyj
│  │  │      │  SpringbootIceCallClientApplication.java #springweb启动类
│  │  │      │
│  │  │      ├─ice
│  │  │      │  ├─java
│  │  │      │  │  ├─client
│  │  │      │  │  │      IceClient.java      #java客户端
│  │  │      │  │  │
│  │  │      │  │  └─server
│  │  │      │  │          IceService.java    #java服务端
│  │  │      │  │
│  │  │      │  ├─servant
│  │  │      │  │      ClientServant.java     #客户端实现 
│  │  │      │  │      ServerServant.java     #服务端实现 
│  │  │      │  │
│  │  │      │  └─spring
│  │  │      │      ├─client
│  │  │      │      │      IceClient.java     #srping客户端
│  │  │      │      │
│  │  │      │      └─server
│  │  │      │              IceService.java   #srping服务端
│  │  │      │
│  │  │      └─util
│  │  │              SpringContextUtil.java
│  │  │
│  │  └─slice2java
│  │          Callback_IServerCallBack_response.java
│  │          Callback_IServer_request.java
│  │          Callback_IServer_setCallBack.java
│  │          IServer.java
│  │          IServerCallBack.java
│  │          IServerCallBackHolder.java
│  │          IServerCallBackPrx.java
│  │          IServerCallBackPrxHelper.java
│  │          IServerCallBackPrxHolder.java
│  │          IServerHolder.java
│  │          IServerPrx.java
│  │          IServerPrxHelper.java
│  │          IServerPrxHolder.java
│  │          _IServerCallBackDisp.java
│  │          _IServerCallBackOperations.java
│  │          _IServerCallBackOperationsNC.java
│  │          _IServerDisp.java
│  │          _IServerOperations.java
│  │          _IServerOperationsNC.java
│  │
│  └─resources
│      │    application.properties #springweb项目
│      ├─lib
│      │
│      │    Identity.ice #ice公共文件 拷贝至此解除软件环境依赖
│      └─slice
│              call.ice  #ice协议文件
│
└─test
    └─java
        └─com
            └─zyj
                    SpringbootIceCallClientApplicationTests.java

2、公共代码

call.ice

#include <E:\SpringWorkSpace\springboot-ice-demo\springboot-ice-call\src\main\resources\lib\Identity.ice>
module slice2java{
/****************
  ice客户端
*****************/
interface IServerCallBack {
/****************
  客户端处理服务端返回
*****************/
bool response(string msg);
};

/***************
  ice服务端
****************/
interface IServer {
/***************
  服务端设置客户端回调对象
****************/
 bool setCallBack(Ice::Identity id);
/***************
  服务端处理客户端请求
****************/
 bool request(string msg);
 };
};
ice文件解释

#include 标识当前ice文件包含其他文件
E:\SpringWorkSpace\springboot-ice-demo\springboot-ice-call\src\main\resources\lib\Identity.ice 为ice公共文件


/****************
  注释内容
*****************/

ClientServant.java

package com.zyj.ice.servant;

import Ice.Current;
import slice2java._IServerCallBackDisp;


/**
 * @author by zyj
 * @version V1.0
 * @Description:
 * @Date 2019/8/6 21:13
 */
@Service
//spring模式bean托管
public class ClientServant extends _IServerCallBackDisp {


    /**
     * 客户端处理服务端返回
     *
     * @param msg
     * @param __current The Current object for the invocation.
     **/

    @Override
    public boolean response(String msg, Current __current) {
        System.out.println("serverCallBack:" + msg);
        return false;
    }
}

ServerServant.java

package com.zyj.ice.servant;

import Ice.*;
import org.springframework.stereotype.Service;
import slice2java.IServerCallBackPrx;
import slice2java.IServerCallBackPrxHelper;
import slice2java._IServerDisp;


/**
 * @author by zyj
 * @version V1.0
 * @Description:
 * @Date 2019/8/6 21:13
 */
@Service
//spring模式使用bean托管
public class ServerServant extends _IServerDisp {


    /**
     * 服务端设置客户端回调对象
     *
     * @param id
     * @param __current The Current object for the invocation.
     **/
    @Override
    public boolean setCallBack(Identity id, Current __current) {
        IServerCallBackPrx iServerCallBackPrx = IServerCallBackPrxHelper.uncheckedCast(__current.con.createProxy(id));
        iServerCallBackPrx.ice_getConnection().setCallback(new ConnectionCallback() {

            @Override
            public void heartbeat(Connection c) {

                System.out.println("sn:" + " client heartbeat....");
            }

            @Override
            public void closed(Connection c) {

                System.out.println("sn:" + " " + "closed....");
            }
        });
        // 每30/2 s向对方做心跳
        // 客户端向服务端做心跳 服务端打印服务端的con.setCallback(new Ice.ConnectionCallback()
        iServerCallBackPrx.ice_getConnection().setACM(new IntOptional(10), new Optional<ACMClose>(ACMClose.CloseOff),
                new Optional<ACMHeartbeat>(ACMHeartbeat.HeartbeatAlways));

        return true;
    }

    /**
     * 服务端处理客户端请求
     *
     * @param msg
     * @param __current The Current object for the invocation.
     **/
    @Override
    public boolean request(String msg, Current __current) {
        System.out.println("client:" + msg);
        return false;
    }


}

3、java实现

step1: ServerServant 实现服务端  如上

setp2:配置server 

package com.zyj.ice.java.server;

import com.zyj.ice.servant.ServerServant;

/**
 * @author by zyj
 * @version V1.0
 * @Description:
 * @Date 2019/8/6 21:13
 */
public class IceService {
    /**
     * 服务名
     */
    private static final String SERVER_NAME = "Hello";
    /**
     * 服务端点
     */
    private static final String SERVER_ENDPOINT = "tcp -p 10006";


    public static void main(String[] args) {
        //获取实现类 SpringContextUtil.getBean(helloServant)
        ServerServant serverServant = new ServerServant();

        //ice通信器
        Ice.Communicator communicator = null;
        try {
            //初始化ice通信器communicator,可以使用args传入一下ice初始化的参数如超时时间,线程池大小等
            communicator = Ice.Util.initialize(args);

            //创建一个名为queryEmployeeAdapter的适配器并且默认使用tcp协议  服务部署在10.4.30.81机器上 服务开启10006监听端口

            Ice.ObjectAdapter adapter = communicator.createObjectAdapterWithEndpoints(SERVER_NAME, SERVER_ENDPOINT);

            // 将servant与ice对象标识符建立映射关系,并添加到ice对象适配器中
            adapter.add(serverServant, Ice.Util.stringToIdentity(SERVER_NAME));

            // 激活对象适配器
            adapter.activate();

            System.out.println("服务启动");
            // 服务在退出之前一直保持监听状态
            communicator.waitForShutdown();

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //异常销毁通信器
            if (communicator != null) {
                communicator.destroy();
            }
        }
    }


}

step3:IceClient 实现ClientServant

step4:IceClient 连接server并设置回调

package com.zyj.ice.java.client;

import Ice.Identity;
import Ice.StringHolder;
import com.zyj.ice.servant.ClientServant;
import slice2java.IServerPrx;
import slice2java.IServerPrxHelper;

/**
 * @author by zyj
 * @version V1.0
 * @Description:
 * @Date 2019/8/6 21:13
 */
public class IceClient {

    /**
     * 服务名
     */
    private static final String SERVER_NAME = "Hello";
    /**
     * 服务端点
     */
    private static final String SERVER_ENDPOINT = "tcp -h 127.0.0.1 -p 10006";


    public static void main(String[] args) {
        //ice通信器
        Ice.Communicator communicator = null;
        try {
            //初始化ice通信器communicator,可以使用args传入一下ice初始化的参数如超时时间,线程池大小等
            communicator = Ice.Util.initialize(args);

            //构建服务端的代理对象  服务端对象标识以 SERVER_NAME:SERVER_ENDPOINT 格式
            Ice.ObjectPrx op = communicator.stringToProxy(SERVER_NAME + ":" + SERVER_ENDPOINT);

            //检查通用客户端代理op 是不是queryServer对象标识符所关联的ice对象的代理
            IServerPrx qp = IServerPrxHelper.checkedCast(op);

            if (qp == null) {
                throw new Exception("qp == null");
            }

            //测试发送信息到户无端
            boolean result = qp.request("hello");

            // 输出服务端返回结果
            System.out.println("java:client请求结果:" + result + " 时间:" + System.currentTimeMillis());


            //创建客户端服务
            Ice.ObjectAdapter adapter = communicator.createObjectAdapter("");
            Ice.Identity id = new Identity();
            id.name = "client";
            id.category = "";
            ClientServant clientServant = new ClientServant();
            adapter.add(clientServant, id);
            adapter.activate();

            //客户端服务设置服务端点
            qp.ice_getConnection().setAdapter(adapter);

            //设置回调对象
            qp.setCallBack(id);
            //设置心跳回调
            qp.ice_getConnection().setCallback(new Ice.ConnectionCallback() {
                @Override
                public void heartbeat(Ice.Connection c) {
                    System.out.println("sn:" + " server heartbeat....");
                }

                @Override
                public void closed(Ice.Connection c) {
                    System.out.println("sn:" + " " + "closed....");
                }
            });
            // 每30/2 s向对方做心跳
            // 客户端向服务端做心跳 服务端打印服务端的con.setCallback(new Ice.ConnectionCallback()
            qp.ice_getConnection().setACM(new Ice.IntOptional(10), new Ice.Optional<Ice.ACMClose>(Ice.ACMClose.CloseOff),
                    new Ice.Optional<Ice.ACMHeartbeat>(Ice.ACMHeartbeat.HeartbeatAlways));

        } catch (Exception e) {
            e.printStackTrace();

        }
    }

}

step5:启动验证

启动server

 启动client

4、spring实现(spring启动ice)

step1:改造ServerServant(添加@Service注解)同上

 step2:改造server  主要防止ice阻塞,所以通过线程处理

package com.zyj.ice.spring.server;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author by zyj
 * @version V1.0
 * @Description:
 * @Date 2019/8/6 21:13
 */
@Service
public class IceService implements Runnable{

    /**服务名*/
    private static final String SERVER_NAME="Hello";
    /**服务端点*/
    private static final String SERVER_ENDPOINT="tcp -p 10006";

    @Autowired
    private HelloServant helloServant;

    @PostConstruct
    private void startIceServer() {
        //构造线程池启动当前任务
        LinkedBlockingQueue<Runnable> runnableList=new LinkedBlockingQueue<Runnable>();
        ThreadPoolExecutor threadPoolExecutor= new ThreadPoolExecutor(100,100,1L, TimeUnit.SECONDS,runnableList);
        threadPoolExecutor.execute(this);
    }


    @Override
    public void run() {
        //ice通信器
        Ice.Communicator communicator = null;
        try {
            //初始化ice通信器communicator,可以使用args传入一下ice初始化的参数如超时时间,线程池大小等
            communicator = Ice.Util.initialize();

            //创建一个名为queryEmployeeAdapter的适配器并且默认使用tcp协议  服务部署在10.4.30.81机器上 服务开启10006监听端口

            Ice.ObjectAdapter adapter = communicator.createObjectAdapterWithEndpoints(SERVER_NAME,SERVER_ENDPOINT);

            // 将servant与ice对象标识符建立映射关系,并添加到ice对象适配器中
            adapter.add(helloServant, Ice.Util.stringToIdentity(SERVER_NAME));

            // 激活对象适配器
            adapter.activate();

            System.out.println("服务启动");
            // 服务在退出之前一直保持监听状态
            communicator.waitForShutdown();

        } catch (Exception e) {
            e.printStackTrace();
        } finally{
            //异常销毁通信器
            if(communicator != null){
                communicator.destroy();
            }
        }

    }
}

step3:IceClient 实现ClientServant(添加@Service注解)同上

step4:改造客户端(客户端连接服务端后,可以保持服务端xxxPrx对象持续调用)

package com.zyj.ice.spring.client;

import Ice.Identity;
import com.zyj.ice.servant.ClientServant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import slice2java.IServerPrx;
import slice2java.IServerPrxHelper;

import javax.annotation.PostConstruct;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author by zyj
 * @version V1.0
 * @Description:
 * @Date 2019/8/6 21:13
 */
@Service
public class IceClient implements Runnable {

    /**
     * 服务名
     */
    private static final String SERVER_NAME = "Hello";
    /**
     * 服务端点
     */
    private static final String SERVER_ENDPOINT = "tcp -h 127.0.0.1 -p 10006";

    @Autowired
    private ClientServant clientServant;

    @PostConstruct
    private void startIceClient() {
        //构造线程启动客户端
        LinkedBlockingQueue<Runnable> runnableList = new LinkedBlockingQueue<Runnable>();
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(100, 100, 1L, TimeUnit.SECONDS, runnableList);
        threadPoolExecutor.execute(this);
    }


    @Override
    public void run() {
        //ice通信器
        Ice.Communicator communicator = null;
        try {
            //初始化ice通信器communicator,可以使用args传入一下ice初始化的参数如超时时间,线程池大小等
            communicator = Ice.Util.initialize();

            //构建服务端的代理对象  服务端对象标识以 SERVER_NAME:SERVER_ENDPOINT 格式
            Ice.ObjectPrx op = communicator.stringToProxy(SERVER_NAME + ":" + SERVER_ENDPOINT);

            //检查通用客户端代理op 是不是queryServer对象标识符所关联的ice对象的代理
            IServerPrx qp = IServerPrxHelper.checkedCast(op);

            if (qp == null) {
                throw new Exception("qp == null");
            }

            //测试发送信息到户无端
            boolean result = qp.request("hello");

            // 输出服务端返回结果
            System.out.println("spring:client请求结果:" + result + " 时间:" + System.currentTimeMillis());


            //创建客户端服务
            Ice.ObjectAdapter adapter = communicator.createObjectAdapter("");
            Ice.Identity id = new Identity();
            id.name = "client";
            id.category = "";
            adapter.add(clientServant, id);
            adapter.activate();

            //客户端服务设置服务端点
            qp.ice_getConnection().setAdapter(adapter);

            //设置回调对象
            qp.setCallBack(id);
            //设置心跳回调
            qp.ice_getConnection().setCallback(new Ice.ConnectionCallback() {
                @Override
                public void heartbeat(Ice.Connection c) {
                    System.out.println("sn:" + " server heartbeat....");
                }

                @Override
                public void closed(Ice.Connection c) {
                    System.out.println("sn:" + " " + "closed....");
                }
            });
            // 每30/2 s向对方做心跳
            // 客户端向服务端做心跳 服务端打印服务端的con.setCallback(new Ice.ConnectionCallback()
            qp.ice_getConnection().setACM(new Ice.IntOptional(10), new Ice.Optional<Ice.ACMClose>(Ice.ACMClose.CloseOff),
                    new Ice.Optional<Ice.ACMHeartbeat>(Ice.ACMHeartbeat.HeartbeatAlways));

        } catch (Exception e) {
            e.printStackTrace();

        }
    }
}

step:5: 启动

三 项目git  https://github.com/HandsomeMars/springboot-ice-demo

https://github.com/HandsomeMars/springboot-ice-demo

猜你喜欢

转载自blog.csdn.net/qq_22211217/article/details/100540465
ice