使用Java语言的Socket API,我们能够实现一个简单的RPC调用,在这个例子中,包括了服务的接口及接口的远端实现、服务的消费者与远端的提供方。基于TCP协议所实现的RPC的类图:

1463890335757166139.jpg

服务的接口和实现都非常简单,它提供了一个SayHello方法,它有一个String类型的参数,通过该参数来识别究竟是返回hello还是返回byebye,代码如下:

pulic interface SayHelloService {

/**

*问好的接口

*@param helloArg 参数

*@retrun

*/

public String sayHello(String helloArg);

}

服务的实现:

public class SayHelloServiceImpl implements SayHelloService {

@Override

public String sayHello(String helloArg) {

if(helloArg.equls("hello")) {

return "hello";

} else {

return "bye bye";

}

}

}

服务消费者Consumer类的部分关键代码:

//接口名称

String interfacename = SayHelloService.class.getName();

//需要远程执行的方法

Method method = SayHelloService.class.getMethod("sayHello", java.lang.String.class);

//需要传递到远端的参数

Object[] arguments = {"hello"};

Socket socket = new Socket("127.0.0.1", 1234);

ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream());

output.writeUTF(interfacename); //接口名称

output.writeUTF(method.getName()); //方法名称

output.writeObject(method.getParameterTypes());

output.writeObject(arguments);

//从远端读取方法执行结果

ObjectInputStream input = new ObjectInputStream(socket.getInputStream());

Object result = input.readObject();

先取得接口的名称、需求调用的方法和需要传递的参数,并通过Socket将其发送到服务提供方,等待服务端响应结果。此处为了便于演示,使用的是阻塞式I/O,实际的生产环境中出于性能考虑,往往使用非阻塞式I/O,以提高更大的吞吐量。

服务提供者Provider类的部分关键代码:

ServiceSocket server = new ServiceSocket(1234);

while(true) {

Socket socket = service.accept();

//读取服务信息

ObjectInputStream input = new ObjectInputStream(scoket.getInputStream());

String interfacename = input.readUTF(); //接口名称

String methodName = input.readUTF(); //方法名称

Class>[] parameterTypes = (Class>[])input.readObject(); //参数类型

Object[] arguments = (Object[])input.readObject(); //参数对象

//执行调用

Class serviceinterfaceclass = Class.forName(interfacename); //得到接口的class

Object service services.get(interfacename); //得到服务实现的对象

Method method = serviceinterfaceclass.getMethod(methodName, parameterTypes);//获得要调用的方法

Object result = method.invoke(service, arguments);

ObjectOutputString output = new ObjectOutputStream(socket.getOutputStream());

output.writeObject(result);

}

服务提供端事先将服务实例化好后房租service这个Map中(此次涉及服务的路由,被简化了,在以后的文章中会做出说明),通过一个while循环,不断地接收新到来的请求,得到所需要的参数,包括接口名称、方法名称、参数类型和参数,通过java的反射取得接口中需求调用的方法,执行后将结果返回给服务的消费者。

在真实的生产环境中,常常是多个客服端同时发送多个请求道服务器,服务端则需要实现同时接收和处理多个客服端的请求,涉及并发处理、服务路由、复杂均衡等。

java基于tcp的rpc调用_JAVA中如何实现基于TCP协议的RPC调用?相关推荐

  1. java中 参数的调用_Java中的参数调用

    Java程序设计语言使用值调用.也就是说.方法得到的是所有参数值的一个拷贝,特别是,方法不能修改传递给它的任何参数变量的内容. 下面说明下这种情况.假定一个方法试图将一个参数值增加至3倍: publi ...

  2. java web 过滤器 拦截器 监听器_Java中的拦截器和过滤器,可不是同一个东西

    过滤器(Filter) 过滤器就如上面的水质过滤器一样,把管道中的水进行一遍过滤再使用.过滤器基于filter接口中的doFilter回调函数,主要的用途是设置字符集.控制权限.控制转向.做一些业务逻 ...

  3. java io和nio的区别_Java中IO和NIO的本质和区别

    导读热词 简介 终于要写到java中最最让人激动的部分了IO和NIO.IO的全称是input output,是java程序跟外部世界交流的桥梁,IO指的是java.io包中的所有类,他们是从java1 ...

  4. java super是引用变量吗_Java中super的几种用法并与this的区别

    1.     子类的构造函数如果要引用super的话,必须把super放在函数的首位. class Base { Base() { System.out.println("Base" ...

  5. java 事务管理 子父线程_Java中的父线程与子线程

    参考资料:https://my.oschina.net/hosee/blog/509557 结论:父线程的生命周期与子线程没有关系. 个人感觉:每个线程包括main线程(除了守护线程)都是平级关系,不 ...

  6. java怎样获取线程的进度_java中的多线程——进度2

    多线程总结: 1,进程和线程的概念. |--进程:是一块包含了某些资源的内存区域.操作系统利用进程把它的工作划分为一些功能单元: 最小的内存单元: 是具有一定独立功能的程序关于某个数据集合上的一次运行 ...

  7. java网页统计访客量_Java中的访客设计模式

    java网页统计访客量 Visitor Design Pattern is one of the behavioral design pattern. 访客设计模式是行为设计​​模式之一. 访客设计模 ...

  8. java设计功能怎么实现代码_Java中的门面设计模式及如何用代码实现

    门面设计模式又叫外观设计模式,其核心思想正如其字面意思,向用户提供一个门户,用户只需要访问这个门户来获取他们想要的数据,无需管理这个门户内部的构成,也无需知道里面的运行流程等等,对于开发者来说,使用门 ...

  9. 用java获取一维数组的平均值_java中一维数组常见运算

    本教程操作环境:windows7系统.java10版,DELL G3电脑. 1.数组求和public class Main { public static void main(String[] arg ...

  10. 用java比较abc大小的程序_Java中 abc + '/'和abc + /的区别

    好吧,写这篇博客又是因为一个有趣的帖子.原问题是"String str = "abc" + '/';和"abc" + "/";的区 ...

最新文章

  1. sql基线建立-知识准备
  2. vsftp虚拟用户无法上传文件,解决办法
  3. 前端学习(3293):effect hook
  4. 2018 支付宝Java开发四面:Ngnix+MQ队列+集群+并发抢购
  5. linux 解压tar.jz,linux系统压缩文件和解压缩命令
  6. java scanner_Java Scanner match()方法与示例
  7. Java中的IO流(六)
  8. 汉语拼音/pinyin4j
  9. 2017级C语言大作业 - 奇怪的大冒险
  10. echarts 生成 迁徙图_Echarts4+EchartsGL 3D迁徙图(附源码)
  11. Red Giant VFX Suite for mac(电影级视觉特效插件)
  12. 基于锁的并发数据结构
  13. 计算机连接打印机连接打印机,怎么连接打印机.教您怎么连接打印机
  14. Serenity框架官方文档翻译3.1(教程)
  15. MMD导入unity中使用
  16. 南开大学计算机宁博,周亚训 教授
  17. 密码就快要彻底消失了,没有人怀念它
  18. 面向毕业、职称的SCI论文高效写作方法
  19. 图片img标签设置默认图片
  20. 你在客户那到底算老几

热门文章

  1. ADB Interface驱动安装[Android Studio开发]
  2. win7声音图标不见,此图标当前处于未活动状态
  3. 八部众---走出软件作坊:三五个人十来条枪 如何成为开发正规军(二十三)
  4. android 控件宽度自适应_自适应各Android手机屏幕尺寸的解决方法
  5. 顺序表 —— Java附加代码
  6. 开课吧java广告,开课吧Java面试题:虚引用与软引用和弱引用的区别
  7. 缓存架构技术:开课吧java高级架构师第七期笔记
  8. 计算机无纸化考试官网,我校《计算机与互联网》课程无纸化考试取得圆满成功...
  9. 40行代码的Python爬虫案例:虎牙-王者荣耀主播的人气排行
  10. android 模拟器介绍