手动编写一个 RPC 调用

  1. package com.alibaba.study.rpc.framework;
  2.  
  3. import java.io.ObjectInputStream;
  4. import java.io.ObjectOutputStream;
  5. import java.lang.reflect.InvocationHandler;
  6. import java.lang.reflect.Method;
  7. import java.lang.reflect.Proxy;
  8. import java.net.ServerSocket;
  9. import java.net.Socket;
  10.  
  11. /**
  12. * Created by baizhuang on 2019-04-03.
  13. */
  14. public class RpcFramework {
  15.  
  16. /**
  17. * 暴露服务
  18. * service : 服务实现
  19. * port: 服务端口
  20. */
  21. public static void export(final Object service,int port)throws Exception{
  22. if(service == null){
  23. throw new IllegalArgumentException("service == null");
  24. }
  25. if(port<=0||port>65535){
  26. throw new IllegalArgumentException("port invalid:"+port);
  27. }
  28. System.out.println("Export service:"+service.getClass().getName()+" on port :"+port );
  29. ServerSocket server= new ServerSocket(port);
  30. while(true){
  31. try{
  32. final Socket socket = server.accept();
  33. new Thread(new Runnable() {
  34. @Override
  35. public void run() {
  36. try{
  37. try{
  38. ObjectInputStream input = new ObjectInputStream(socket.getInputStream());
  39. try{
  40. String methodName = input.readUTF();
  41. Class<?>[] parameterTypes = (Class<?>[])input.readObject();
  42. Object[] arguments = (Object[])input.readObject();
  43. ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream());
  44. try{
  45. Method method = service.getClass().getMethod(methodName,parameterTypes);
  46. Object result = method.invoke(service,arguments);
  47. output.writeObject(result);
  48. }catch (Throwable t){
  49. output.writeObject(t);
  50. }finally {
  51. output.close();
  52. }
  53. }finally {
  54. input.close();
  55. }
  56. }finally {
  57. socket.close();
  58. }
  59. }catch (Exception e){
  60. e.printStackTrace();
  61. }
  62. }
  63. }).start();
  64. }catch (Exception e){
  65. e.printStackTrace();
  66. }
  67. }
  68.  
  69. }
  70.  
  71. /**
  72. * 引用服务
  73. */
  74.  
  75. public static <T> T refer(final Class<T> interfaceClass,final String host,final int port)throws Exception{
  76. if(interfaceClass == null){
  77. throw new IllegalArgumentException("interface class == null");
  78. }
  79. if(!interfaceClass.isInterface()){
  80. throw new IllegalArgumentException("The" + interfaceClass.getClass().getName()+"must be interface");
  81. }
  82. if(host == null|| host.length()==0){
  83. throw new IllegalArgumentException("host == null");
  84. }
  85. System.out.println("Get remote Service:"+interfaceClass.getName()+" from server "+host+":"+port);
  86. return (T)Proxy.newProxyInstance(interfaceClass.getClassLoader(), new Class<?>[]{interfaceClass}, new InvocationHandler() {
  87. @Override
  88. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  89. Socket socket = new Socket(host,port);
  90. try{
  91. ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream());
  92. try{
  93. output.writeUTF(method.getName());
  94. output.writeObject(method.getParameterTypes());
  95. output.writeObject(args);
  96. ObjectInputStream input = new ObjectInputStream(socket.getInputStream());
  97. try{
  98. Object result = input.readObject();
  99. if(result instanceof Throwable){
  100. throw (Throwable)result;
  101. }
  102. return result;
  103. }finally {
  104. input.close();
  105. }
  106. }finally {
  107. output.close();
  108. }
  109. }finally {
  110. socket.close();
  111. }
  112. }
  113. });
  114. }
  115. }

接口以及实现

  1. package com.alibaba.study.rpc.test;
  2.  
  3. /**
  4. * Created by baizhuang on 2019-04-03.
  5. */
  6. public interface HelloService {
  7. String hello(String name);
  8. }
  1. package com.alibaba.study.rpc.test;
  2.  
  3. /**
  4. * Created by baizhuang on 2019-04-03.
  5. */
  6. public class HelloServiceImpl implements HelloService{
  7. @Override
  8. public String hello(String name) {
  9. return "Hello"+name;
  10. }
  11. }

服务提供方

  1. package com.alibaba.study.rpc.test;
  2.  
  3. import com.alibaba.study.rpc.framework.RpcFramework;
  4.  
  5. /**
  6. * Created by baizhuang on 2019-04-03.
  7. */
  8. public class RpcProvider {
  9. public static void main(String[] args) throws Exception{
  10. HelloService service = new HelloServiceImpl();
  11. RpcFramework.export(service,1234);
  12. }
  13. }

服务客户端

  1. package com.alibaba.study.rpc.test;
  2.  
  3. import com.alibaba.study.rpc.framework.RpcFramework;
  4.  
  5. /**
  6. * Created by baizhuang on 2019-04-03.
  7. */
  8. public class RpcConsumer {
  9. public static void main(String[] args) throws Exception{
  10. HelloService service = RpcFramework.refer(HelloService.class,"127.0.0.1",1234);
  11. for(int i=0;i<Integer.MAX_VALUE;i++){
  12. String hello = service.hello("World : "+i);
  13. System.out.println(hello);
  14. Thread.sleep(1000);
  15. }
  16. }
  17. }

编写一个 rpc的更多相关文章

  1. 如何设计一个RPC系统

    版权声明:本文由韩伟原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/162 来源:腾云阁 https://www.qclou ...

  2. 如何设计一个 RPC 系统

    本文由云+社区发表 RPC是一种方便的网络通信编程模型,由于和编程语言的高度结合,大大减少了处理网络数据的复杂度,让代码可读性也有可观的提高.但是RPC本身的构成却比较复杂,由于受到编程语言.网络模型 ...

  3. 从零开始基于go-thrift创建一个RPC服务

    Thrift 是一种被广泛使用的 rpc 框架,可以比较灵活的定义数据结构和函数输入输出参数,并且可以跨语言调用.为了保证服务接口的统一性和可维护性,我们需要在最开始就制定一系列规范并严格遵守,降低后 ...

  4. 手写一个RPC框架

    一.前言 前段时间看到一篇不错的文章<看了这篇你就会手写RPC框架了>,于是便来了兴趣对着实现了一遍,后面觉得还有很多优化的地方便对其进行了改进. 主要改动点如下: 除了Java序列化协议 ...

  5. 编写一个通用的Makefile文件

    1.1在这之前,我们需要了解程序的编译过程 a.预处理:检查语法错误,展开宏,包含头文件等 b.编译:*.c-->*.S c.汇编:*.S-->*.o d.链接:.o +库文件=*.exe ...

  6. CSharpGL(34)以从零编写一个KleinBottle渲染器为例学习如何使用CSharpGL

    CSharpGL(34)以从零编写一个KleinBottle渲染器为例学习如何使用CSharpGL +BIT祝威+悄悄在此留下版了个权的信息说: 开始 本文用step by step的方式,讲述如何使 ...

  7. .NET Core RC2发布在即,我们试着用记事本编写一个ASP.NET Core RC2 MVC程序

    在.NET Core 1.0.0 RC2即将正式发布之际,我也应应景,针对RC2 Preview版本编写一个史上最简单的MVC应用.由于VS 2015目前尚不支持,VS Code的智能感知尚欠火候,所 ...

  8. 网络爬虫:使用Scrapy框架编写一个抓取书籍信息的爬虫服务

      上周学习了BeautifulSoup的基础知识并用它完成了一个网络爬虫( 使用Beautiful Soup编写一个爬虫 系列随笔汇总 ), BeautifulSoup是一个非常流行的Python网 ...

  9. 作业二:个人编程项目——编写一个能自动生成小学四则运算题目的程序

    1. 编写一个能自动生成小学四则运算题目的程序.(10分)   基本要求: 除了整数以外,还能支持真分数的四则运算. 对实现的功能进行描述,并且对实现结果要求截图.   本题发一篇随笔,内容包括: 题 ...

随机推荐

  1. Firefox控制台日志转入文件

    应该说这个需求并不常见-但有时候我的确想过,要是能知道Firefox此时在干吗就好了–有那么几次,该运行的脚本没有运行,状态条显示页面的加载并未完成,但你却永远等不到它. 意外地是,谷哥和度娘似乎并不 ...

  2. 20175236 《Java程序设计》实验一(Java开发环境的熟悉)实验报告

    一.实验报告封面 课程:Java程序设计 班级:1752班 姓名:温丰帆 学号:20175236 指导教师:娄嘉鹏 实验日期:2019年4月2日 实验时间:13:45 - 15:25 实验序号:实验一 ...

  3. # 20175311 2018-2019-2 《Java程序设计》第2周学习总结

    ## 教材学习内容总结 第二周我对如何运行java程序已经比较熟悉了,第二周更多的是注重程序内部的原理了. ## 教材学习中的问题和解决过程 - 问题1:看书时看到的一个例子,不是很懂它是怎么得出结果 ...

  4. case class 和class的区别以及构造器参数辨析

    工作中偶然发现Scala构造方法中的参数,无论是否有val/var修饰都可以顺利编译运行,如下: class AA(name: String) class BB(val name: String) 那 ...

  5. axios与vue的配合使用事例,实现缓存和重复加载的控制

    import Vue from "vue"; import qs from "qs"; import Store from "../vuex/stor ...

  6. koa-passport实现本地验证

    安装 yarn add koa-passport passport-local 先看下passport.js登录策略,判断用户和密码 const passport = require('koa-pas ...

  7. java——collection总结

    Collection 来源于Java.util包,是非常实用常用的数据结构!!!!!字面意思就是容器.具体的继承实现关系如下图,先整体有个印象,再依次介绍各个部分的方法,注意事项,以及应用场景.   ...

  8. 数据库索引的数据结构b+树

    b+树的查找过程:如上图所示,如果要查找数据项29,那么首先会把磁盘块1由磁盘加载到内存,此时发生一次IO,在内存中用二分查找确定29在17和35之间,锁定磁盘块1的P2指针,             ...

  9. Maintaining ICM Parameters for Using SSL for As JAVA

    1770585 - How to configure SSL on the AS Java You can use this procedure to configure the necessary ...

  10. Python中的split()函数的用法

    函数:split() Python中有split()和os.path.split()两个函数,具体作用如下:split():拆分字符串.通过指定分隔符对字符串进行切片,并返回分割后的字符串列表(lis ...