简单rpc 框架的实现

RPC(Romote Procedure Call):远程过程调用,允许一台计算机程序远程调用另外一台计算机的子程序,不用关心底层,网络通信,在socket基础上实现,比socket需要更多资源。

简单rpc 框架的实现

先看demo实现 如下 分为client端和server端

 

简单rpc 框架的实现

Client实现如下:

接口

package com.gupao.rmi.Demo.rpcClient; 

    public interface HelloService {

        StringsayHello(String msg);

    }

package com.gupao.rmi.Demo.rpcClient;

import java.lang.reflect.Proxy;

import java.net.InetSocketAddress;

/**

*客户端代理

*/

public class Client {

public T clientProy(Class className, InetSocketAddress address) {

    return (T) Proxy.newProxyInstance(className.getClassLoader(), new Class[] {className},

                new RemoteHandler(address, className));

    }

}

建立socket发送数据

package com.gupao.rmi.Demo.rpcClient;

import java.io.ObjectInputStream;

import java.io.ObjectOutputStream;

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

import java.net.InetSocketAddress;

import java.net.Socket;

public class RemoteHandlerimplements InvocationHandler {

private InetSocketAddressaddress;

    private ClassaClass;

    public RemoteHandler(InetSocketAddress address, Class aClass) {

            this.address = address;

            this.aClass = aClass;

    }

    @Override

    public Objectinvoke(Object proxy, Method method, Object[] args)throws Throwable {

        Socket socket =null;

        Object result =null;

        ObjectInputStream objectInputStream =null;

        ObjectOutputStream objectOutputStream =null;

        try {

            socket =new Socket();

            socket.connect(address);

            objectOutputStream =new ObjectOutputStream(socket.getOutputStream());

            //发送接口名

            objectOutputStream.writeUTF(aClass.getName());

            //发送方法名

            objectOutputStream.writeUTF(method.getName());

            //参数类型

            objectOutputStream.writeObject(method.getParameterTypes());

            //参数名称

            objectOutputStream.writeObject(args);

            objectOutputStream.flush();

            objectInputStream =new ObjectInputStream(socket.getInputStream());

            result = objectInputStream.readObject();

            objectOutputStream.close();

            objectInputStream.close();

        } catch (Exception e) {

            e.printStackTrace();

        } finally {

             if (objectInputStream !=null) objectInputStream.close();

            if (objectOutputStream !=null) objectOutputStream.close();

            if (!socket.isClosed()) socket.close();

        }

                return result;

    }

}

测试类

package com.gupao.rmi.Demo.rpcClient;

import java.net.InetSocketAddress;

public class TestRpcClient {

    public static void main(String[] args) {

        HelloService helloService =new Client().clientProy(HelloService.class, new         InetSocketAddress("127.0.0.1", 8080));

        System.out.print(helloService.sayHello("wxw"));

    }

}

Server 端 接口

package com.gupao.rmi.Demo.rpcServer;

    public interface HelloService {

        StringsayHello(String msg);

    }

实现类

package com.gupao.rmi.Demo.rpcServer;

public class HelloServiceImplimplements HelloService {

    @Override

    public StringsayHello(String msg) {

        return "hello" + msg;

    }

}

建立服务端

package com.gupao.rmi.Demo.rpcServer;

import java.io.IOException;

import java.net.InetSocketAddress;

import java.net.ServerSocket;

import java.net.Socket;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

public class ServiceServer {

    //启用线程池

    private static final ExecutorServiceexecutorService = Executors.newCachedThreadPool();

    private int port =0;

    public ServiceServer(int port) {

        this.port = port;

    }

public void start() {

ServerSocket serverSocket =null;

        Socket socket =null;

        try {

                try {

                    System.out.print("打开服务ServerSocket");

                    serverSocket =new ServerSocket();

                    serverSocket.bind(new InetSocketAddress(port));

                    socket = serverSocket.accept();

                    //等待客户端连接启动线程用于多个任务调用服务端

                    while (true) {

                        System.out.print("客户端开始连接服务...");

                        executorService.execute(new ServiceTask(socket));

                }

        } catch (IOException e) {

            e.printStackTrace();

            }

    } catch (Exception e) {

        e.printStackTrace();

       }

   }

}

服务端接受数据并处理

package com.gupao.rmi.Demo.rpcServer;

import java.io.IOException;

import java.io.ObjectInputStream;

import java.io.ObjectOutputStream;

import java.lang.reflect.InvocationTargetException;

import java.lang.reflect.Method;

import java.net.Socket;

public class ServiceTaskimplements Runnable {

private Socketsocket;

    public ServiceTask(Socket socket) {

            this.socket = socket;

    }

    @Override

    public void run() {

            //做服务传输通信用字节流的方式实现

            ObjectOutputStream objectOutputStream =null;

            ObjectInputStream objectInputStream =null;

        try {

                System.out.print("客户端已经连接...");

                objectInputStream =new ObjectInputStream(socket.getInputStream());

                //获取客户端发送过来的接口

                String name = objectInputStream.readUTF();

                / /获取客户端发送过来的方法名称

              String methodName = objectInputStream.readUTF();

             //获取客户端参数类型

            Class[] methodTypes = (Class[])objectInputStream.readObject();

            //获取客户端的参数值

            Object[] args = (Object[]) objectInputStream.readObject();

            //获取从客户传来的方法

            Class className = name.getClass();

            Method method = className.getMethod(methodName, methodTypes);

            Object result = method.invoke(className.newInstance(), args);

            objectOutputStream =new ObjectOutputStream(socket.getOutputStream());

            objectOutputStream.writeObject(result);

            objectInputStream.close();

            objectOutputStream.close();

        } catch (IOException | ClassNotFoundException | NoSuchMethodException |

                InstantiationException | IllegalAccessException | InvocationTargetException e) {

                e.printStackTrace();

        } finally {

    try {

                if (objectInputStream !=null) objectInputStream.close();

                if (objectOutputStream !=null ) objectOutputStream.close();

                if (!socket.isClosed())socket.close();

            }  catch (IOException e) {

                e.printStackTrace();

            }

            }

    }

}

启动服务端

public class TestRpcServer {

    public static void main(String[] args) {

            ServiceServer serviceServer =new ServiceServer(8080);

            serviceServer.start();

    }

}