超级简单的java实现RPC框架,详细见代码
package com.blackeyes.demo.rpc;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.net.ServerSocket;
import java.net.Socket;
public class RpcFramework {
public static void main(String[] args) {
new Thread(()->{
RpcService rpcService = (str)->{return "hello " + str;};
try {
RpcFramework.export(rpcService, 1234);
} catch (IOException e) {
e.printStackTrace();
}
}).start();
new Thread(()->{
RpcService service = RpcFramework.refer(RpcService.class, "127.0.0.1", 1234);
int i= 0;
while(true) {
System.out.println(service.sayHello("远方的朋友 " + i++));
try {
Thread.sleep(1000 * i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
interface RpcService {
String sayHello(String str);
}
public static void export(RpcService service, int port) throws IOException {
ServerSocket server = new ServerSocket(port);
while(true) {
final Socket socket = server.accept();
new Thread(()->{
try {
ObjectInputStream input = new ObjectInputStream(socket.getInputStream());
String methodName = input.readUTF();
Class<?>[] parameterTypes = (Class<?>[])input.readObject();
Object[] arguments = (Object[])input.readObject();
ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream());
Method method = service.getClass().getMethod(methodName, parameterTypes);
Object result = method.invoke(service, arguments);
output.writeObject(result);
} catch (IOException | ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
}).start();
}
}
public static <T> T refer(final Class<T> interfaceClss, String host, int port){
return (T) Proxy.newProxyInstance(interfaceClss.getClassLoader(), new Class[]{interfaceClss}, (proxy, method, args)->{
Socket socket = new Socket(host, port);
ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream());
output.writeUTF(method.getName());
output.writeObject(method.getParameterTypes());
output.writeObject(args);
return new ObjectInputStream(socket.getInputStream()).readObject();
});
}
}