简单实现RPC远程过程调用


思路:
1.先建立一个service 和其实现类 如下
serviceImpl
2.需要创建一个代理服务器类 来完成与客户端的通信

3.代理服务器类 需要调用线程池的execute()方法 来实现业务调用 所以需要些一个线程类ProxyHandler

public class ProxyHandler implements Runnable {

private Socket socket;//客户端套接字
private Object service;//服务,也就是调用方法的对象

public ProxyHandler(Socket socket, Object service) {
    this.socket = socket;
    this.service = service;
}

@Override
public void run() {

    System.out.println("开始执行服务端的处理方法");

    ObjectInputStream objectInputStream=null;
    ObjectOutputStream objectOutputStream=null;
    try {
        //先接受客户端发送过来的数据
        objectInputStream=new ObjectInputStream(socket.getInputStream());

        //反序列化  里面应该包含 请求那个服务(那个接口)  方法名 参数数组
        RPCRequest request= (RPCRequest) objectInputStream.readObject();

        //通过反射 调用方法
        Object result=myInvoke(request);

        //把服务端的结果,序列化后传回客户端
        objectOutputStream=new ObjectOutputStream(socket.getOutputStream());
        objectOutputStream.writeObject(result);
        objectOutputStream.flush();


    } catch (IOException e) {
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } catch (NoSuchMethodException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        e.printStackTrace();
    }finally {
        if (objectOutputStream!=null){
            try {
                objectInputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

/**
 * 通过反射调用了服务端的方法
 * @param request
 * @return
 * @throws NoSuchMethodException
 * @throws InvocationTargetException
 * @throws IllegalAccessException
 */
private Object myInvoke(RPCRequest request) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {

    Object[] parameters = request.getParameters();
    Class<?>[] types = new Class[parameters.length];
    //把参数转化为对应的类对象
    for (int i = 0; i <types.length ; i++) {
        types[i]=parameters[i].getClass();
    }

    //getMethod方法  第一个参数就是方法名, 第二个参数就是方法参数对应的类对象  如String.class
    Method method=service.getClass().getMethod(request.getMethodName(),types);

    //invoke()方法 第一个参数为调用方法的对象,第二个参数为方法对应的参数列表
    Object result=method.invoke(service,parameters);

    return result;
}

.其请求中所需要三个参数 及时 类名,方法名,参数 可以封装成一个类 RPCRequest

4.server整体框架图

启动服务端

下面进行客户端的编写

1.client图

启动客户端

因为客户端只有接口,没有实现类,所以需要创建个代理类(JDK动态代理实现调用服务器方法) 提示:客户端和服务端通用的代码 比如 IHelloService
RPCRequest 等 可以提取出来

代理类:
创建代理类

代理类需要一个InvocationHandler 所以自定义一个RemoteInvocationHandler 把端口号和主机传递过去

这里需要定义一个传输层 (就是和服务端进行传递数据)
ublic class RPCNetTransport {

private String host;
private int port;

public RPCNetTransport() {
}

public RPCNetTransport(String host, int port) {
    this.host = host;
    this.port = port;
}

private Socket newSocket(){
    System.out.println("建立一个新的连接");
    Socket socket=null;
    try {
        socket=new Socket(host,port);
    } catch (Exception e) {
        System.out.println("建立连接失败");
    }

    return socket;
}

public Object send(RPCRequest request){
    Socket socket=null;

    try {
        //把客户端的数据request 直接发送过去
        socket=newSocket();
        ObjectOutputStream objectOutputStream=new ObjectOutputStream(socket.getOutputStream());
        objectOutputStream.writeObject(request);
        objectOutputStream.flush();

        //获取服务器返回的结果
        ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream());
        Object result=objectInputStream.readObject();
        objectInputStream.close();
        objectOutputStream.close();
        return result;
    } catch (Exception e) {
        throw new RuntimeException("数据发送异常"+e);
    }finally {
        if (socket!=null){
            try {
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}

}

基本功能就可以运行了 如下:

服务端:

客户端:

到此一个简单的RPC通信到此结束!

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值