自定义RPC框架的简单实现

package com.remote.service;

/**
 * Created by 79782 on 2018/7/22.
 */
public interface HelloService {
    public String sayHello(String name);
}
package com.remote.service;

/**
 * Created by 79782 on 2018/7/22.
 */
public class HelloServiceImpl implements HelloService {
    public String sayHello(String name) {
        return "hello:"+name;
    }
}
package com.remote.server;

/**
 * Created by 79782 on 2018/7/22.
 */
public interface Server {
    public void start();
    public void stop();
    public void register(Class server ,Class serviceImpl);
}
package com.remote.server;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Method;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Created by 79782 on 2018/7/22.
 */
public class ServerCenter implements Server {
    private static HashMap<String,Class> serviceRegiser=new HashMap();
    private static int port;
    private static ExecutorService executor= Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
    private static boolean isRunning=false;
    public static void setPort(int port) {
        ServerCenter.port = port;
    }

    public void start() {
        isRunning=true;
        ServerSocket server=null;
        try {
            server=new ServerSocket();
            server.bind(new InetSocketAddress(9999));
        } catch (IOException e) {
            e.printStackTrace();
        }
        while(true){

            try {
                //等待客户端连接 接受客户端连接及请求
                Socket socket = server.accept();
                executor.execute(new ServiceTask(socket));

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

    }

    public void stop() {
        isRunning=false;
        executor.shutdown();
    }

    public void register(Class server ,Class serviceImpl) {
        serviceRegiser.put(server.getName(),serviceImpl);
    }

    private static class ServiceTask implements Runnable{
        private Socket socket;

        public ServiceTask() {
        }

        public ServiceTask(Socket socket) {
            this.socket = socket;
        }

        public void run() {
            ObjectInputStream ois=null;
            ObjectOutputStream oos =null;
            try {
                //Object流有顺序
                ois= new ObjectInputStream(socket.getInputStream());
                //因为ObjectInputeStream对发送数据的数据严格要求,所以可以一个一个接受
                String serviceName=ois.readUTF();
                String methodName=ois.readUTF();
                Class[] paramType= (Class[]) ois.readObject();
                Object[] arguments= (Object[]) ois.readObject();
                //根据请求找到请求的接口
                Class serviceClass = serviceRegiser.get(serviceName);
                Method method = serviceClass.getMethod(methodName, paramType);
                Object result=method.invoke(serviceClass.newInstance(), arguments);
                oos= new ObjectOutputStream(socket.getOutputStream());
                oos.writeObject(result);
            }catch (Exception e) {
                e.printStackTrace();
            }finally {
                if(oos!=null){
                    try {
                        oos.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if(ois!=null){
                    try {
                        ois.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}

package com.remote.client;

import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.net.InetSocketAddress;
import java.net.Socket;

/**
 * Created by 79782 on 2018/7/22.
 */
public class Client {
    //获取代表服务端接口的动态代理对象
    //serviceName:客户端向服务端请求的接口名
    @SuppressWarnings("unchecked")
    public static <T> T getRemoteProxyObj(final Class serviceInterface, final InetSocketAddress addr){
        return (T)Proxy.newProxyInstance(serviceInterface.getClassLoader(), new Class<?>[]{serviceInterface}, new InvocationHandler() {
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                ObjectOutputStream oos=null;
                ObjectInputStream ois=null;
                try{
                    Socket socket=new Socket();
                    socket.connect(addr);
                    oos= new ObjectOutputStream(socket.getOutputStream());
                    //接口名、接口方法名、方法类型,方法参数、
                    oos.writeUTF(serviceInterface.getName());
                    oos.writeUTF(method.getName());
                    oos.writeObject(method.getParameterTypes());
                    oos.writeObject(args);
                    //等待服务端处理
                    //服务端处理返回结果
                    ois= new ObjectInputStream(socket.getInputStream());
                    return ois.readObject();
                }catch (Exception e){
                    e.printStackTrace();
                    return null;
                }finally {
                    if(ois!=null){
                        ois.close();
                    }
                    if(oos!=null){
                        oos.close();
                    }
                }
            }
        });


    }
}
package com.remote.server;

import com.remote.service.HelloService;
import com.remote.service.HelloServiceImpl;

/**
 * Created by 79782 on 2018/7/22.
 */
public class ServerMain {
    /**
        服务端将可以提供的接口注册到服务中心 通过map保存key:发布接口的名字,value:接口的实现类
        服务端接收客户端请求后,通过请求的接口名在服务中心的map中寻找对应的接口实现类。
        解析客户端发送的方法名,接口名,解析完毕后通过反射技术将该方法执行
        执行完毕后将结果返回给客户端

    */
    public static void main(String[] args) {
       new Thread(new Runnable() {
           public void run() {
               Server server=new ServerCenter();
               server.register(HelloService.class, HelloServiceImpl.class);
               server.start();
           }
       }).start();
    }
}
package com.remote.client;

import com.remote.service.HelloService;

import java.net.InetSocketAddress;

/**
 * Created by 79782 on 2018/7/22.
 */
public class ClientMain {
    public static void main(String[] args) throws ClassNotFoundException {
        /**
         * 客户端通过socket请求服务端,并且通过字符串形式将请求的接口名发送给服务端
         * 动态代理:发送接口名,方法参数
         */

        HelloService helloService=Client.getRemoteProxyObj(
                Class.forName("com.remote.service.HelloService"),
                new InetSocketAddress("127.0.0.1",9999));
        System.out.println(helloService.sayHello("yanfang"));
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章