编写一个 rpc
手动编写一个 RPC 调用
package com.alibaba.study.rpc.framework; 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.ServerSocket;
import java.net.Socket; /**
* Created by baizhuang on 2019-04-03.
*/
public class RpcFramework { /**
* 暴露服务
* service : 服务实现
* port: 服务端口
*/
public static void export(final Object service,int port)throws Exception{
if(service == null){
throw new IllegalArgumentException("service == null");
}
if(port<=0||port>65535){
throw new IllegalArgumentException("port invalid:"+port);
}
System.out.println("Export service:"+service.getClass().getName()+" on port :"+port );
ServerSocket server= new ServerSocket(port);
while(true){
try{
final Socket socket = server.accept();
new Thread(new Runnable() {
@Override
public void run() {
try{
try{
ObjectInputStream input = new ObjectInputStream(socket.getInputStream());
try{
String methodName = input.readUTF();
Class<?>[] parameterTypes = (Class<?>[])input.readObject();
Object[] arguments = (Object[])input.readObject();
ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream());
try{
Method method = service.getClass().getMethod(methodName,parameterTypes);
Object result = method.invoke(service,arguments);
output.writeObject(result);
}catch (Throwable t){
output.writeObject(t);
}finally {
output.close();
}
}finally {
input.close();
}
}finally {
socket.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}).start();
}catch (Exception e){
e.printStackTrace();
}
} } /**
* 引用服务
*/ public static <T> T refer(final Class<T> interfaceClass,final String host,final int port)throws Exception{
if(interfaceClass == null){
throw new IllegalArgumentException("interface class == null");
}
if(!interfaceClass.isInterface()){
throw new IllegalArgumentException("The" + interfaceClass.getClass().getName()+"must be interface");
}
if(host == null|| host.length()==0){
throw new IllegalArgumentException("host == null");
}
System.out.println("Get remote Service:"+interfaceClass.getName()+" from server "+host+":"+port);
return (T)Proxy.newProxyInstance(interfaceClass.getClassLoader(), new Class<?>[]{interfaceClass}, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Socket socket = new Socket(host,port);
try{
ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream());
try{
output.writeUTF(method.getName());
output.writeObject(method.getParameterTypes());
output.writeObject(args);
ObjectInputStream input = new ObjectInputStream(socket.getInputStream());
try{
Object result = input.readObject();
if(result instanceof Throwable){
throw (Throwable)result;
}
return result;
}finally {
input.close();
}
}finally {
output.close();
}
}finally {
socket.close();
}
}
});
}
}
接口以及实现
package com.alibaba.study.rpc.test; /**
* Created by baizhuang on 2019-04-03.
*/
public interface HelloService {
String hello(String name);
}
package com.alibaba.study.rpc.test; /**
* Created by baizhuang on 2019-04-03.
*/
public class HelloServiceImpl implements HelloService{
@Override
public String hello(String name) {
return "Hello"+name;
}
}
服务提供方
package com.alibaba.study.rpc.test; import com.alibaba.study.rpc.framework.RpcFramework; /**
* Created by baizhuang on 2019-04-03.
*/
public class RpcProvider {
public static void main(String[] args) throws Exception{
HelloService service = new HelloServiceImpl();
RpcFramework.export(service,1234);
}
}
服务客户端
package com.alibaba.study.rpc.test; import com.alibaba.study.rpc.framework.RpcFramework; /**
* Created by baizhuang on 2019-04-03.
*/
public class RpcConsumer {
public static void main(String[] args) throws Exception{
HelloService service = RpcFramework.refer(HelloService.class,"127.0.0.1",1234);
for(int i=0;i<Integer.MAX_VALUE;i++){
String hello = service.hello("World : "+i);
System.out.println(hello);
Thread.sleep(1000);
}
}
}
编写一个 rpc的更多相关文章
- 如何设计一个RPC系统
版权声明:本文由韩伟原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/162 来源:腾云阁 https://www.qclou ...
- 如何设计一个 RPC 系统
本文由云+社区发表 RPC是一种方便的网络通信编程模型,由于和编程语言的高度结合,大大减少了处理网络数据的复杂度,让代码可读性也有可观的提高.但是RPC本身的构成却比较复杂,由于受到编程语言.网络模型 ...
- 从零开始基于go-thrift创建一个RPC服务
Thrift 是一种被广泛使用的 rpc 框架,可以比较灵活的定义数据结构和函数输入输出参数,并且可以跨语言调用.为了保证服务接口的统一性和可维护性,我们需要在最开始就制定一系列规范并严格遵守,降低后 ...
- 手写一个RPC框架
一.前言 前段时间看到一篇不错的文章<看了这篇你就会手写RPC框架了>,于是便来了兴趣对着实现了一遍,后面觉得还有很多优化的地方便对其进行了改进. 主要改动点如下: 除了Java序列化协议 ...
- 编写一个通用的Makefile文件
1.1在这之前,我们需要了解程序的编译过程 a.预处理:检查语法错误,展开宏,包含头文件等 b.编译:*.c-->*.S c.汇编:*.S-->*.o d.链接:.o +库文件=*.exe ...
- CSharpGL(34)以从零编写一个KleinBottle渲染器为例学习如何使用CSharpGL
CSharpGL(34)以从零编写一个KleinBottle渲染器为例学习如何使用CSharpGL +BIT祝威+悄悄在此留下版了个权的信息说: 开始 本文用step by step的方式,讲述如何使 ...
- .NET Core RC2发布在即,我们试着用记事本编写一个ASP.NET Core RC2 MVC程序
在.NET Core 1.0.0 RC2即将正式发布之际,我也应应景,针对RC2 Preview版本编写一个史上最简单的MVC应用.由于VS 2015目前尚不支持,VS Code的智能感知尚欠火候,所 ...
- 网络爬虫:使用Scrapy框架编写一个抓取书籍信息的爬虫服务
上周学习了BeautifulSoup的基础知识并用它完成了一个网络爬虫( 使用Beautiful Soup编写一个爬虫 系列随笔汇总 ), BeautifulSoup是一个非常流行的Python网 ...
- 作业二:个人编程项目——编写一个能自动生成小学四则运算题目的程序
1. 编写一个能自动生成小学四则运算题目的程序.(10分) 基本要求: 除了整数以外,还能支持真分数的四则运算. 对实现的功能进行描述,并且对实现结果要求截图. 本题发一篇随笔,内容包括: 题 ...
随机推荐
- VSS2005源代码管理启用http方式
一直在使用vss管理源代码,在服务器上使用文件共享当方式.最近安全形式升级,禁止使用文件共享,因此要升级到http方式. 按照网上的教程,一路前行. 1.登录服务器桌面,打开vss administr ...
- CSS的块级元素和内联元素的概念
三生有幸,偶然之下知道了<CSS世界>这本书,让我产生了探究 CSS 的想法. 这里对 CSS 中的块级元素和内联元素的概念做一个简单的整理. 可能对于我们前端开发人员来讲,一般接触到的元 ...
- analyse idoc by creation date
t-code ZMM0127 infoset: ZMM_IDOC_READ_01 go to code: AUTHORITY-CHECK OBJECT 'S_IDOCMONI'ID 'ACTVT' F ...
- AD服务无法启动
转自网络资源:http://www.great-one.co.uk/archives/289 版本:win08 : 该方法支持hyper-v 虚拟机 启动报错: A Windows 2008 R2 D ...
- 数据帧、MTU、MSS、IP分片
1.以太网帧 在以太网链路上的数据包称作以太帧,在802.3标准里,规定了一个以太帧的数据部分(Payload)的最大长度是1500个字节(MTU),再加上14字节链路头和4字节的FCS,所以以太网帧 ...
- List集合去重
本篇包含了两种去重,一种是List集合去重,一种是两个List集合去重合并 List集合去重,一般是两种方式,一种是遍历list集合判断后赋给另一个list集合,一种是用赋给set集合再返回给list ...
- asp代码写的,微信会员报名转发分享带上下级和邀约人关系并且能微信支付asp编号的
昨天晚上应一个客户要求写了一套代码,实现的功能是: 在微信公众号上注册会员,获取用户的头像和微信名称,进入会员中心报名,报名成功成功后,他如果转发链接给别人,别人打开后则成为他的下级,上面那个算是一个 ...
- java+Selenium+TestNg搭建自动化测试架构(3)实现POM(page+Object+modal)
1.Page Object是Selenium自动化测试项目开发实践的最佳设计模式之一,通过对界面元素的封装减少冗余代码,同时在后期维护中,若元素定位发生变化,只需要调整页面元素封装的代码,提高测试用例 ...
- sql注入、csrf
◎sql注入产生的原因?又如何防御sql注入? SQL注入,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令.具体来说,它是利用现有应用 ...
- 导入myeclipse的java源码查看不了的问题
导入之前自己的jar包后 ,可以正常使用了,但是发现按ctrl+鼠标左键查看不了源代码.attach source 来源后,还是没有效果. 先添加所要使用的jar包, 然后再添加源文件.最后终于显示成 ...