rpc 原理和简单实现
来源:互联网 发布:ansible.cfg mac 编辑:程序博客网 时间:2024/06/05 02:19
首先你必须了解什么是RPC, (百度知道)
RPC(Remote Procedure Call Protocol)——远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数据。在OSI网络通信模型中,RPC跨越了传输层和应用层。RPC使得开发包括网络分布式多程序在内的应用程序更加容易。
结构:(图片来源:cnblogs.com/shown)
对比本地JAVA 和 RPC代码:
1)本地模式
1)本地模式
a)本地的接口:
package example1.day20170625;/** * Created by chenfenggang on 2017/7/17. */public interface Calculator { int sum(int a,int b);}
b)本地的实现
package day20170625;/** * Created by chenfenggang on 2017/7/17. */public class MyCalculator implements Calculator{ public int sum(int a, int b) { return a+b; }}
c)本地的测试
package day20170625;/** * Created by chenfenggang on 2017/7/17. */public class TestMyCalculator { public static void main(String[] args) { Calculator calculator = new MyCalculator(); System.out.println(calculator.sum(1,2)); }}
2) 加代理。不实现方法
package day20170625;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;/** * Created by chenfenggang on 2017/7/17. */public class MyInvocatationHandler<T> implements InvocationHandler { private Class target; MyInvocatationHandler(Class target) { super(); this.target = target; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println(target); System.out.println(method.getName()); System.out.println(args.length); for(Object object:args){ System.out.println(object); } return 11; } public <T>T getObject(){ return (T) Proxy.newProxyInstance(target.getClassLoader(), new Class<?>[]{target}, new MyInvocatationHandler(target)) ; } public static void main(String[] args) { Calculator calculator = (Calculator) new MyInvocatationHandler<Calculator>(Calculator.class).getObject(); System.out.println(calculator.sum(1,2)); }}
这样不管调用什么都会调用invoke方法。如果将这部分变成一个基于io或者nio的东西,就能读取远程的对象。
3)客户端加入Socket
package day20170625;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.Socket;/** * Created by chenfenggang on 2017/7/17. */public class MyRpcClient<T> implements InvocationHandler { private Class target; MyRpcClient(Class target) { super(); this.target = target; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Socket socket = new Socket("localhost",8080); ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream()); objectOutputStream.writeObject(target.getName()); objectOutputStream.writeObject(method.getName()); objectOutputStream.writeObject(method.getParameterTypes()); objectOutputStream.writeObject(args); return new ObjectInputStream(socket.getInputStream()).readObject(); } public <T>T getObject(){ return (T) Proxy.newProxyInstance(target.getClassLoader(), new Class<?>[]{target}, new MyRpcClient(target)) ; } public static void main(String[] args) { Calculator calculator = (Calculator) new MyRpcClient<Calculator>(Calculator.class).getObject(); System.out.println(calculator.sum(123,10)); System.out.println(calculator.delete(123,10)); }}
4)服务端读取客户端请求,反射对象
package day20170625;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.HashMap;import java.util.Map;/** * Created by chenfenggang on 2017/7/17. */public class RpcService { //存储接口与实现类的关系,当然也可以通过客户端传送实现类的类名 static Map<String ,Class> classImpMap = new HashMap(); public static void put(String name,Class clazz){ classImpMap.put(name,clazz); } public static void run() throws IOException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException { ServerSocket serverSocket = new ServerSocket(8080); while (true){ Socket socket = serverSocket.accept(); ObjectInputStream inputStream =new ObjectInputStream( socket.getInputStream()); ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream()); String calssName = (String)inputStream.readObject(); String methodName = (String)inputStream.readObject(); Class<?>[] parameterTypes = (Class<?>[]) inputStream.readObject(); Object[] arguments = (Object[]) inputStream.readObject(); Class clazz = null; if(calssName!=null) { //需要获取接口的实现类 clazz = classImpMap.get(calssName); } if(clazz==null){ continue; } Method method = clazz.getMethod(methodName,parameterTypes); Object result = method.invoke(clazz.newInstance(), arguments); objectOutputStream.writeObject(result); } } public static void main(String[] args) { try { RpcService.put(Calculator.class.getName(),MyCalculator.class); RpcService.run(); } catch (Exception e) { e.printStackTrace(); } }}
5)总结:
RPC优点:
1)客户端只需要接口就像,不用管复杂的实现,
2) 实现代码在服务端运行,可以充分利用服务端代码优势。
阅读全文
0 0
- rpc 原理和简单实现
- RPC原理和实现
- 简单了解RPC实现原理
- 简单的RPC原型与实现原理
- rpc 简单原理
- RPC框架简单原理
- Rpc原理与实现
- RPC原理及实现
- RPC原理及实现
- 简单的RPC实现
- 简单实现的RPC
- RPC过程简单实现
- rpc 简单实现
- Netty实现简单RPC
- 基于TCP和HTTP协议的RPC简单实现
- 基于TCP和HTTP协议的RPC简单实现
- pomelo的rpc实现原理
- Spark RPC实现原理分析
- PC端windows与虚拟机linux之间文件的传输方式总结
- 使MFC中的ListCtrl控件的列宽固定不可变
- Mac下secureCRT连接VMware Fusion上面的虚拟机超时的解决方法
- Axis2入门小项目-使用RPC方式调用WebService
- CyclicBarrier 公共屏障点
- rpc 原理和简单实现
- Struts2教程系列(四) 验证码
- 支持向量机Python实现
- jQuery基础知识
- Java代码规范
- java 练习题
- python15正则表达式
- [记录]关于GC - 待续
- <划重点的UNITY2017> 物理系统概述