手寫簡單RPC

1. 獲取接口對應的實現類
package com.rpc.server.util;
import java.io.File;
import java.net.URL;
import com.alibaba.fastjson.JSON;java

public class ClassUtils {
    public static Object getSubClassByInterface(ClassLoader loader, String packName, Class<?> interfaceCls) {
        Object instance = null;
        try {
            if ("".equals(packName)) {
                return null;
            }
            String calssPath = packName.replace(".", "/");
            URL url = loader.getResource(calssPath);
            File file = new File(url.getFile());
            File[] filelist = file.listFiles();
            for (File file2 : filelist) {
                if (file2.isDirectory()) {
                    String subPackName = packName + "." + file2.getName();
                    System.out.println("directory path " + calssPath);
                    return getSubClassByInterface(loader, subPackName, interfaceCls);
                } else {
                    String targetClsPath = packName + "." + file2.getName();
                    Class<?> object = Class.forName(targetClsPath.replace(".class", ""));
                    if (interfaceCls.isAssignableFrom(object)&&!interfaceCls.equals(object)) {
                        System.out.println("target class impl " + JSON.toJSONString(object));
                        instance = object.newInstance();
                        return instance;
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    
    public static void main(String[] args) {
//        ClassUtils classUtils = new ClassUtils();
//        classUtils.getSubClassByInterface(classUtils.getClass().getClassLoader(),"com.rpc.server", IHelloService.class, IHelloServiceImpl.class);
    }
}
----------------------------------------------------------------------
2. RpcProcessor使用socket接收請求數據處理並返回結果
package com.rpc.server;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Method;
import java.net.Socket;
import com.alibaba.fastjson.JSON;
import com.rpc.server.util.ClassUtils;json

public class RpcProcessor implements Runnable {
    private Socket newSocket = null;
    private String packageName;
    public RpcProcessor(Socket newSocket, String packageName) {
        this.newSocket = newSocket;
        this.packageName = packageName;
    }
    @Override
    public void run() {
        ObjectInputStream inputStream = null;
        ObjectOutputStream outputStream = null;
        try {
            System.out.println("start process client request");
            inputStream = new ObjectInputStream(newSocket.getInputStream());
            RpcRequest request = (RpcRequest) inputStream.readObject();
            Class<?> clazz = Class.forName(request.getClassName());
            Object serviceImpl = ClassUtils.getSubClassByInterface(this.getClass().getClassLoader(), packageName, clazz);
            System.out.println(JSON.toJSONString(request));
            Method method = clazz.getMethod(request.getMethodName(), request.getTypes());
            Object result = method.invoke(serviceImpl, request.getArguments());
            outputStream = new ObjectOutputStream(newSocket.getOutputStream());
            outputStream.writeObject(result);
            outputStream.flush();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (inputStream != null) inputStream.close();
                if (outputStream != null) outputStream.close();
            } catch (IOException e2) {
                e2.printStackTrace();
            }
            
        }
    }
}
----------------------------------------------------------------------
3. 請求參數實體
package com.rpc.server;
import java.io.Serializable;
public class RpcRequest implements Serializable{
    private static final long serialVersionUID = 1L;
    private String serviceId;
    private String className;
    private String methodName;
    private Class<?>[] types;
    private Object[] arguments;
    public String getServiceId() {
        return serviceId;
    }
    public void setServiceId(String serviceId) {
        this.serviceId = serviceId;
    }
    public String getClassName() {
        return className;
    }
    public void setClassName(String className) {
        this.className = className;
    }
    public String getMethodName() {
        return methodName;
    }
    public void setMethodName(String methodName) {
        this.methodName = methodName;
    }
    public Class<?>[] getTypes() {
        return types;
    }
    public void setTypes(Class<?>[] types) {
        this.types = types;
    }
    public Object[] getArguments() {
        return arguments;
    }
    public void setArguments(Object[] arguments) {
        this.arguments = arguments;
    }
}
----------------------------------------------------------------------
4.RpcServer發佈服務
package com.rpc.server;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;socket

public class RpcServer {    
    private String host;
    private int port;        
    private String packageName;
    private ExecutorService executorService = Executors.newFixedThreadPool(5);
    public RpcServer(String host, int port, String packageName) {
        super();
        this.host = host;
        this.port = port;
        this.packageName = packageName;
    }
    public boolean publisher() {
        ServerSocket serverSocket = null;
        try {
            serverSocket = new ServerSocket();
            serverSocket.bind(new InetSocketAddress(host, port));
            executorService.execute(new RpcProcessor(serverSocket.accept(), packageName));
        } catch (Exception e) {
            System.out.println("RpcServer publisher exception " + e.getMessage());
        } finally {
            try {
                if (null != serverSocket) serverSocket.close();
            } catch (IOException e) {
                System.out.println("close socket eception " + e.getMessage());
                return false;
            }
        }
        return true;
    }
    
}
----------------------------------------------------------------------
5. 測試
package com.rpc.server;
public class ServerMain {
    public static void main(String[] args) {    
        new Thread(new Runnable() {
            @Override
            public void run() {
                RpcServer server = null;
                boolean ret = true;
                while (ret) {
                    server = new RpcServer("localhost", 9090, "com.rpc.server");
                    ret = server.publisher();
                }
            }
        }).start();    
    }
}
----------------------------------------------------------------------
6. RPC 客戶端代理類
package com.proxy.demo;
import java.lang.reflect.Proxy;
public class RemoteProxy<T> {
    private Class<?> serverClass;
    private String host;
    private int port;
    public RemoteProxy(Class<?> serverClass, String host, int port) {
        this.serverClass = serverClass;
        this.host = host;
        this.port = port;
    }
    @SuppressWarnings("unchecked")
    public T newProxy() {
        Class<?>[] interfaces = {serverClass};
        ClassLoader classLoader = serverClass.getClassLoader();
        RemoteRpcHandler handler = new RemoteRpcHandler(serverClass, host, port);
        return (T) Proxy.newProxyInstance(classLoader, interfaces, handler);
    }
}
----------------------------------------------------------------------
7.客戶端回調
package com.proxy.demo;
import java.io.IOException;
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;
import com.rpc.server.RpcRequest;
public class RemoteRpcHandler implements InvocationHandler {
    private int port;
    private String host;
    private Class<?> intefaceClaxx;
    public RemoteRpcHandler(Class<?> intefaceClaxx, String host, int port) {
        this.host = host;
        this.port = port;
        this.intefaceClaxx = intefaceClaxx;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object result = null;
        System.out.println("start hand remote invoke");
        Socket socket = null;
        ObjectOutputStream outputStream = null;
        ObjectInputStream inputStream = null;
        try {
            socket = new Socket();
            socket.connect(new InetSocketAddress(host, port));
            outputStream = new ObjectOutputStream(socket.getOutputStream());
            RpcRequest request = new RpcRequest();
            request.setClassName(intefaceClaxx.getName());
            request.setArguments(args);
            request.setMethodName(method.getName());
            request.setTypes(method.getParameterTypes());
            outputStream.writeObject(request);
            inputStream = new ObjectInputStream(socket.getInputStream());
            result = inputStream.readObject();
        } catch (Exception e) {
            System.out.println("handler exception " + e.getMessage());
        } finally {
            try {
                if (null != inputStream)
                    inputStream.close();
                if (outputStream != null)
                    outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }
}ide

------------------------------------------------------------------測試

package com.proxy.demo;this

import com.ubs.server.UserInfoService;url

public class RpcMain {
    
    public static void main(String[] args) {
//        RemoteProxy<IHelloService> remote = new RemoteProxy<>(IHelloService.class, "localhost", 9090);
//        IHelloService iHelloService = remote.newProxy();
//        String ret = iHelloService.sayHello("Tom");
//        System.out.println(ret);
        
        RemoteProxy<UserInfoService> remoteProxy = new RemoteProxy<>(UserInfoService.class, "localhost", 9091);
        UserInfoService userInfo = remoteProxy.newProxy();
        System.out.println(userInfo.queryUserName(9890087l));
        
    }
}
 .net

相關文章
相關標籤/搜索