RPC是在Socket的基础上实现的,它比socket需要更多的网络和系统资源。RPC(Remote Procedure Call,远程过程调用)是建立在Socket之上的,出于一种类比的愿望,在一台机器上运行的主程序,可以调用另一台机器上准备好的子程序,就像LPC(本地过程调用).

简单RPC之Socket实现
2016年10月28日 10:54:47

阅读数:2663

最近看到Dubbo大神写得使用Socket实现的简单的RPC调用,对RPC的理解更简单了,然后根据大神的代码自己也重构了一下。

RPC Server端代码,主要是使用ServerSocket获得rpc调用客户端发送过来的类信息,方法信息及方法参数信息,通过反射在RPCServer端进行代码执行,最后将执行结果发送给Socket,第一步需要首先执行RPCServer。

  1. import java.io.IOException;
  2. import java.io.ObjectInputStream;
  3. import java.io.ObjectOutputStream;
  4. import java.lang.reflect.InvocationTargetException;
  5. import java.lang.reflect.Method;
  6. import java.net.ServerSocket;
  7. import java.net.Socket;
  8. import java.util.concurrent.ConcurrentHashMap;
  9. /**
  10. * 服务端
  11. * @author tianjunwei
  12. */
  13. public class RPCServer {
  14. public static ConcurrentHashMap<String, Object> classMap = new ConcurrentHashMap<String,Object>();
  15. public static void main(String [] args) throws Exception{
  16. System.err.println("server start");
  17. RPCServer.invoker(8080);
  18. }
  19. public static void invoker(int port) throws Exception{
  20. ServerSocket server = new ServerSocket(port);
  21. for(;;){
  22. try{
  23. final Socket socket = server.accept();
  24. new Thread(new Runnable() {
  25. ObjectOutputStream output =  null;
  26. @Override
  27. public void run() {
  28. try{
  29. try {
  30. output = new ObjectOutputStream(socket.getOutputStream());
  31. ObjectInputStream input = new ObjectInputStream(socket.getInputStream());
  32. String className = input.readUTF();
  33. String methodName = input.readUTF();
  34. Class<?>[] parameterTypes = (Class<?>[])input.readObject();
  35. Object[] arguments = (Object[])input.readObject();
  36. Object claszz = null;
  37. if(!classMap.containsKey(className)){
  38. try {
  39. claszz = Class.forName(className).newInstance();
  40. classMap.put(className, claszz);
  41. } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
  42. e.printStackTrace();
  43. }
  44. }else {
  45. claszz = classMap.get(className);
  46. }
  47. Method method = claszz.getClass().getMethod(methodName, parameterTypes);
  48. Object result = method.invoke(claszz, arguments);
  49. output.writeObject(result);
  50. } catch (IOException | ClassNotFoundException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e) {
  51. output.writeObject(e);
  52. }finally {
  53. output.close();
  54. }
  55. }catch(Exception e){
  56. e.printStackTrace();
  57. }finally {
  58. try {
  59. socket.close();
  60. } catch (IOException e) {
  61. e.printStackTrace();
  62. }
  63. }
  64. }
  65. }).start();
  66. }catch (Exception e) {
  67. e.printStackTrace();
  68. }
  69. }
  70. }
  71. }

RPC 客户端代码,这里利用了代理机制的特性,在执行具体的方法时执行远程调用,执行方法时会调用invoke方法,这样就可以通过Socket向RPCServer发送需要执行的方法的信息,并且获取执行后的结果并返回。

  1. public class RPCProxy {
  2. @SuppressWarnings("unchecked")
  3. public static <T> T create(Object target){
  4. return (T) Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(), new InvocationHandler(){
  5. @SuppressWarnings("resource")
  6. @Override
  7. public Object invoke(Object proxy, Method method, Object[] args)
  8. throws Throwable {
  9. Socket socket = new Socket("localhost", 8080);
  10. ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream());
  11. try {
  12. output.writeUTF(target.getClass().getName());
  13. output.writeUTF(method.getName());
  14. output.writeObject(method.getParameterTypes());
  15. output.writeObject(args);
  16. ObjectInputStream input = new ObjectInputStream(socket.getInputStream());
  17. try {
  18. Object result = input.readObject();
  19. if (result instanceof Throwable) {
  20. throw (Throwable) result;
  21. }
  22. return result;
  23. } finally {
  24. input.close();
  25. }
  26. } finally {
  27. output.close();
  28. socket.close();
  29. }
  30. }
  31. });
  32. }
  33. }

HelloRpc接口:

  1. public interface HelloRpc {
  2. String hello(String name);
  3. }

HelloRpcImpl实现类:

  1. public class HelloRpcImpl implements HelloRpc {
  2. @Override
  3. public String hello(String name) {
  4. return "hello "+name;
  5. }
  6. }

Main函数操作:

  1. public class Main {
  2. public static void main(String [] args){
  3. HelloRpc helloRpc = new HelloRpcImpl();
  4. helloRpc = RPCProxy.create(helloRpc);
  5. System.err.println(helloRpc.hello("rpc"));
  6. }
  7. }

执行结果:

hello rpc

通过以上这个示例我们可能会对一些RPC框架的实现原理有一定的了解,比如和我之前发表的Hessian源码分析有一些相似的地方。示例源码地址github,当然这个实现只是作为一些简单的原理说明,还有很多不足的地方。

hadoop17---RPC和Socket的区别的更多相关文章

  1. RPC和Socket

    RPC和Socket的区别 rpc是通过什么实现啊?socket! RPC(Remote Procedure Call,远程过程调用)是建立在Socket之上的,出于一种类比的愿望,在一台机器上运行的 ...

  2. rpc、socket、mq

    关于RPC与MQ异同的理解 相同:1.都利于大型系统的解耦:2.都提供子系统之间的交互,特别是异构子系统(如java\node等不同开发语言):不同:1.RPC侧重功能调用,因此多半是同步的:备注:也 ...

  3. TCP/IP,HTTP,Socket的区别与联系

    一 忆往昔,尽是悔恨泪.       在学校的时候学过,网络七层,也知道tcp的三次握手.但因为根本没用在实际开发中,所以逐渐淡忘.现在就再次理解下三个的区别与联系. 二 正题       网络七层: ...

  4. Http、tcp、Socket连接区别

    转自Http.tcp.Socket连接区别 相信不少初学手机联网开发的朋友都想知道Http与Socket连接究竟有什么区别,希望通过自己的浅显理解能对初学者有所帮助. 1.TCP连接 要想明白Sock ...

  5. RPC和RMI的区别(Difference Between RPC and RMI)

    RPC和RMI的区别(Difference Between RPC and RMI) RPC vs RMI RPC (Remote Procedure Call) and RMI (Remote Me ...

  6. TCP/IP、Http、Socket的区别与关系

    --TCP/IP.Http.Socket的区别与关系 --------------------------------------2014/05/14 网络由下往上分为 物理层.数据链路层.网络层.传 ...

  7. SOA,Webservice,SOAP,REST,RPC,RMI的区别与联系

    SOA,Webservice,SOAP,REST,RPC,RMI的区别与联系 SOA面向服务的软件架构(Service Oriented Architecture) 是一种计算机软件的设计模式,主要应 ...

  8. RPC与RMI的区别

    分布式项目按照以下发展经历了以下技术: CORBA: RMI:基于远程接口的调用 RMI-RROP:这是RMI与CORBA的结合,用在了EJB技术上,EJB留给世界上是优秀的理论和糟糕的架构. WEB ...

  9. WebSocket和Socket的区别

    前段时间写了两篇介绍HTTP和WebSocket的文章,回复中有人说希望了解下WebSocket和Socket的区别.这个问题之前也有想过,自己对此是有大概的答案,可是并不太确定,于是去搜集了些资料( ...

  10. TCP socket和web socket的区别

    小编先习惯性的看了下某中文百科网站对Web Socket的介绍,觉得很囧.如果大家按照这个答案去参加BAT等互联网公司的前端开发面试,估计会被鄙视. 还是让我们阅读一些英文材料吧. 让我们直接看sta ...

随机推荐

  1. H.264 Profile

    提到High Profile H.264解码许多人并不了解,那么到底什么是High Profile H.264解码?其应用效果又是如何呢?  作为行业标准,H.264编码体系定义了4种不同的Profi ...

  2. 2014年辛星解读css第一节

    CSS是Cascading Style Sheets的缩写.即层叠样式表,它用于表现HTML的样式,即HTML仅仅是去写该网页有哪些内容,至于怎样去表现它们,由CSS去定制. ************ ...

  3. java pdf 导出方案

    java代码 import com.itextpdf.text.DocumentException; import com.itextpdf.text.pdf.BaseFont; import org ...

  4. boost::bind 详解

    使用 boost::bind是标准库函数std::bind1st和std::bind2nd的一种泛化形式.其可以支持函数对象.函数.函数指针.成员函数指针,并且绑定任意参数到某个指定值上或者将输入参数 ...

  5. group_concat 多对多关联, 统计分组数据, 结果拼接到一个字段

    统计用户所有的角色, 结果: 1   张三    普通用户,管理员,XXX 2  李四    普通用户, XXX select ur.user_id,u.login_name,GROUP_CONCAT ...

  6. fnt 图字原理

    摘自:http://blog.csdn.net/wzq9706/article/details/8188256 首先要介绍一下,图字是怎么来的?其实这个很早很早了,记得80后在95年开始玩DOS下的仙 ...

  7. 【Redis】redis分页查询理解

    偶然在代码中发现一个接口,接口定义说是分页查询,但逻辑实现是Redis.不太理解,Redis怎么分页?后来看到一篇文章,然后了解了. 1.Zrevrange实现 通过SortedSet的zrevran ...

  8. android studio 运行是,app标题栏不显示

    解决办法:让所有的活动都继承 AppCompatActivity就行了,如: public class FirstActivity extends AppCompatActivity{ ... }

  9. finereport-JS

    JS实现定时刷新报表 setInterval("self.location.reload();",10000); //10000ms即每10s刷新一次页面. 注:对于cpt报表,若 ...

  10. Oracle 数据库的组成(instance+database)

    Oracle服务器是一种对象关系数据库管理系统,它为信息管理提供开放.综合.集成的方法. Oracle服务器中有多种进进程.内存结构和文件: Oracle服务器由一个Oracle实例和一个Oracle ...