简单RPC之Socket实现
2016-10-28 10:54
295 查看
最近看到Dubbo大神写得使用Socket实现的简单的RPC调用,对RPC的理解更简单了,然后根据大神的代码自己也重构了一下。
RPC Server端代码,主要是使用ServerSocket获得rpc调用客户端发送过来的类信息,方法信息及方法参数信息,通过反射在RPCServer端进行代码执行,最后将执行结果发送给Socket,第一步需要首先执行RPCServer。
RPC 客户端代码,这里利用了代理机制的特性,在执行具体的方法时执行远程调用,执行方法时会调用invoke方法,这样就可以通过Socket向RPCServer发送需要执行的方法的信息,并且获取执行后的结果并返回。
HelloRpc接口:
Main函数操作:
执行结果:hello rpc
通过以上这个示例我们可能会对一些RPC框架的实现原理有一定的了解,比如和我之前发表的Hessian源码分析有一些相似的地方。示例源码地址github,当然这个实现只是作为一些简单的原理说明,还有很多不足的地方。
RPC Server端代码,主要是使用ServerSocket获得rpc调用客户端发送过来的类信息,方法信息及方法参数信息,通过反射在RPCServer端进行代码执行,最后将执行结果发送给Socket,第一步需要首先执行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.ServerSocket; import java.net.Socket; import java.util.concurrent.ConcurrentHashMap; /** * 服务端 * @author tianjunwei */ public class RPCServer { public static ConcurrentHashMap<String, Object> classMap = new ConcurrentHashMap<String,Object>(); public static void main(String [] args) throws Exception{ System.err.println("server start"); RPCServer.invoker(8080); } public static void invoker(int port) throws Exception{ ServerSocket server = new ServerSocket(port); for(;;){ try{ final Socket socket = server.accept(); new Thread(new Runnable() { ObjectOutputStream output = null; @Override public void run() { try{ try { output = new ObjectOutputStream(socket.getOutputStream()); ObjectInputStream input = new ObjectInputStream(socket.getInputStream()); String className = input.readUTF(); String methodName = input.readUTF(); Class<?>[] parameterTypes = (Class<?>[])input.readObject(); Object[] arguments = (Object[])input.readObject(); Object claszz = null; if(!classMap.containsKey(className)){ try { claszz = Class.forName(className).newInstance(); classMap.put(className, claszz); } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) { e.printStackTrace(); } }else { claszz = classMap.get(className); } Method method = claszz.getClass().getMethod(methodName, parameterTypes); Object result = method.invoke(claszz, arguments); output.writeObject(result); } catch (IOException | ClassNotFoundException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e) { output.writeObject(e); }finally { output.close(); } }catch(Exception e){ e.printStackTrace(); }finally { try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } } }).start(); }catch (Exception e) { e.printStackTrace(); } } } }
RPC 客户端代码,这里利用了代理机制的特性,在执行具体的方法时执行远程调用,执行方法时会调用invoke方法,这样就可以通过Socket向RPCServer发送需要执行的方法的信息,并且获取执行后的结果并返回。
public class RPCProxy { @SuppressWarnings("unchecked") public static <T> T create(Object target){ return (T) Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(), new InvocationHandler(){ @SuppressWarnings("resource") @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Socket socket = new Socket("localhost", 8080); ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream()); try { output.writeUTF(target.getClass().getName()); output.writeUTF(method.getName()); output.writeObject(method.getParameterTypes()); output.writeObject(args); ObjectInputStream input = new ObjectInputStream(socket.getInputStream()); try { Object result = input.readObject(); if (result instanceof Throwable) { throw (Throwable) result; } return result; } finally { input.close(); } } finally { output.close(); socket.close(); } } }); } }
HelloRpc接口:
public interface HelloRpc { String hello(String name); }HelloRpcImpl实现类:
public class HelloRpcImpl implements HelloRpc { @Override public String hello(String name) { return "hello "+name; } }
Main函数操作:
public class Main { public static void main(String [] args){ HelloRpc helloRpc = new HelloRpcImpl(); helloRpc = RPCProxy.create(helloRpc); System.err.println(helloRpc.hello("rpc")); } }
执行结果:hello rpc
通过以上这个示例我们可能会对一些RPC框架的实现原理有一定的了解,比如和我之前发表的Hessian源码分析有一些相似的地方。示例源码地址github,当然这个实现只是作为一些简单的原理说明,还有很多不足的地方。
相关文章推荐
- 简单RPC之Socket实现
- 简单RPC之Socket实现
- 简单RPC之Socket实现
- Java实现一个简单的RPC框架(五) 基于Socket的传输层实现
- Linux下基于C实现的socket简单文件下载实例
- Java 利用套接字Socket实现简单的服务器与客户端通信
- socket编程的c#简单实现
- 简单实现Socket
- C#实现Socket传输简单数据
- 面向连接的Socket Server的简单实现
- Linux下基于C实现的socket简单文件上传实例
- C#实现Socket传输简单数据
- VC写的socket程序实现一个简单Echo服务器端和客户端程序
- 面向连接的Socket Server的简单实现
- 面向连接的Socket Server的简单实现
- Java 利用套接字Socket实现简单的服务器与客户端通信
- 用socket实现简单的文件传输
- 简单的SOcket传送文件字符串实现
- linux下socket实现TCP通信的简单程序接口封装
- 跨平台socket 简单实现