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. 第二百三十七节,Bootstrap图标菜单按钮组件

    Bootstrap图标菜单按钮组件 学习要点: 1.小图标组件 2.下拉菜单组件 3.按钮组组件 4.按钮式下拉菜单 本节课我们主要学习一下 Bootstrap 的三个组件功能:小图标组件.下拉菜单组 ...

  2. 卡友pos机使用流程

    Q: pos机正常使用步骤 A: 1. 按开机键开机2. 输入“01”进行签到3. 系统提示输入密码,密码为“0000”4. 系统提示“请刷卡”,可正常刷卡消费首次使用请务必登陆商户后台核对结算收款账 ...

  3. datagrid使用要点

    table自适应: (fit:true(设置table)) 列自动撑开:fitColumns: true,注意给列的width属性赋值

  4. ModelShowDialog缓存上次浏览的URL

    1. 一种解决方法设置每次清楚浏览的页面. In IE7, go to Tools  |  Internet Options.  Click the Browsing History "Se ...

  5. IIS服务中五种身份验证的灵活运用

    微软IIS服务是一项经典的Web服务,可以为广大用户提供信息发布和资源共享功能.身份认证是保证IIS服务安全的基础机制,IIS支持以下5种 Web 身份认证方法: 一.匿名身份认证 如果启用了匿名访问 ...

  6. IOS学习笔记28—SQLite3第三方库之FMDB

    本文转载至 http://blog.csdn.net/happyrabbit456/article/details/11609451 SQLite是一种小型的轻量级的关系型数据库,在移动设备上使用是非 ...

  7. STL中的容器

    STL中的容器 一. 种类: 标准STL序列容器:vector.string.deque和list. 标准STL关联容器:set.multiset.map和multimap. 非标准序列容器slist ...

  8. border-radius 原理分析

    border-radius 想必大家都有所了解,比较常见的用法就像下面一样: 注意左边的盒子 border-radius: 100px;  右边的为0哦,所以右边的实际上没有设置圆角边框属性:咱们比较 ...

  9. Linux ssh其他服务器

  10. 《挑战程序设计竞赛》2.5 最短路 AOJ0189 2249 2200 POJ3255 2139 3259 3268(5)

    AOJ0189 http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=0189 题意 求某一办公室到其他办公室的最短距离. 多组输入,n表示 ...