简单RPC之Socket实现
来源:互联网 发布:centos rpm snmp 编辑:程序博客网 时间:2024/05/19 19:57
最近看到Dubbo大神写得使用Socket实现的简单的RPC调用,对RPC的理解更简单了,然后根据大神的代码自己也重构了一下。
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;@Overridepublic 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")@Overridepublic 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 {@Overridepublic 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,当然这个实现只是作为一些简单的原理说明,还有很多不足的地方。
1 0
- 简单RPC之Socket实现
- 简单RPC之Socket实现
- Hadoop之RPC简单实现
- 简单RPC实现之Netty实现
- 简单的RPC实现
- 简单实现的RPC
- RPC过程简单实现
- rpc 简单实现
- Netty实现简单RPC
- Java实现一个简单的RPC框架(五) 基于Socket的传输层实现
- Java RMI之HelloWorld 与 Java简单实现RPC
- IOS之rpc实现
- RabbitMQ之RPC实现
- 分布式Web应用----基于Socket+动态代理实现简单RPC 生产者消费者模型
- 简单的RPC java实现
- 简单的RPC java实现
- 自己实现简单RPC功能
- 简单的RPC java实现
- Scala之小括号和花括号(Parentheses & Crurly Braces)
- 切换流程-空口信令
- iOS 对RunTime的一些简单了解
- 切换流程-IMS/SIP信令(wireshark信令)
- IPSEC建立过程
- 简单RPC之Socket实现
- LTE SystemInformationBlockType17
- PHP文件上传类(支持单文件上传,也支持多文件上传)
- LTE RRCConnectionReconfiguration
- 关于采用Unity 5.x 提供的增量式打包单个模型后AssetBundle doesn’t have main asset解决方法
- 高并发解决方案
- Basic SRVCC 基本SRVCC 信令流程
- 仿茄子快传——获取安装应用列表信息
- aSRVCC信令流程(振铃中SRVCC)