rpc_demo
参考:RPC是什么,看完你就知道了 - 知乎 (zhihu.com)
IService.java
package com.hmb; public interface IService { void sayHello(); void sayGoodbye(); }
ServiceImpl.java
package com.hmb; public class ServiceImpl implements IService{ @Override public void sayHello() { System.out.println("hello"); } @Override public void sayGoodbye() { System.out.println("goodbye"); } }
Server.java
package com.hmb; 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.InetSocketAddress; import java.net.ServerSocket; import java.net.Socket; import java.util.HashMap; import java.util.Map; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class Server { private boolean isRun = true; private Map<String, Class> methods = new HashMap<>(); private ExecutorService executors = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); public void register(String interfaceName, Class impl) { methods.put(interfaceName, impl); } public void start() { System.out.println("start server..."); try (ServerSocket serverSocket = new ServerSocket()) { serverSocket.bind(new InetSocketAddress("127.0.0.1", 9999)); while (isRun) { Socket socket = serverSocket.accept(); executors.execute(new ServerTask(socket)); } } catch (IOException e) { throw new RuntimeException(e); } } public void close() { System.out.println("shutdown server..."); isRun = false; executors.shutdown(); } private class ServerTask implements Runnable { private Socket socket; public ServerTask() { } public ServerTask(Socket socket) { this.socket = socket; } @Override public void run() { try (ObjectInputStream ois = new ObjectInputStream(socket.getInputStream()); ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream())){ String interfaceName = ois.readUTF(); String methodName = ois.readUTF(); Class[] parasType = (Class[]) ois.readObject(); Object[] paras = (Object[]) ois.readObject(); Class clazz = methods.get(interfaceName); Method method = clazz.getMethod(methodName, parasType); Object result = method.invoke(clazz.getDeclaredConstructor().newInstance(), paras); oos.writeObject(result); } catch (IOException e) { throw new RuntimeException(e); } catch (ClassNotFoundException e) { throw new RuntimeException(e); } catch (NoSuchMethodException e) { throw new RuntimeException(e); } catch (InvocationTargetException e) { throw new RuntimeException(e); } catch (InstantiationException e) { throw new RuntimeException(e); } catch (IllegalAccessException e) { throw new RuntimeException(e); } } } }
ServerMain.java
package com.hmb; public class ServerMain { public static void main(String[] args) { Server server = new Server(); server.register(IService.class.getName(), ServiceImpl.class); server.start(); } }
Client.java
package com.hmb; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.net.InetSocketAddress; import java.net.Socket; public class Client { public static <T> T getProxyObj(Class interfaceClass, InetSocketAddress address) { System.out.println("start client..."); InvocationHandler invocationHandler = new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { try (Socket socket = new Socket()) { socket.connect(address); ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream()); oos.writeUTF(interfaceClass.getName()); oos.writeUTF(method.getName()); oos.writeObject(method.getParameterTypes()); oos.writeObject(args); ObjectInputStream ois = new ObjectInputStream(socket.getInputStream()); System.out.println("return value from server:" + ois.readObject()); return ois.read(); } catch (Exception e) { System.out.println("invoke exception" + e); return null; } } }; return (T) Proxy.newProxyInstance(interfaceClass.getClassLoader(), new Class<?>[]{interfaceClass}, invocationHandler); } }
ClientMain.java
package com.hmb; import java.net.InetSocketAddress; public class ClientMain { public static void main(String[] args) { IService iService = Client.getProxyObj(IService.class, new InetSocketAddress("localhost", 9999)); iService.sayHello(); iService.sayGoodbye(); } }
先启动服务端,再启动客户端即可得到如下运行结果: