RPC使用java最基本的,传输层使用Socket,序列化使用Serializable,java 动态代理模式,但是未实现消息注册等相关信息

大道至简

server端

 package com.rpc.entity;

 import java.io.Serializable;

 public class RpcObject implements Serializable{

     private static final long serialVersionUID = 1L;
private Class<?> c;
private String methodName;
private Object[] args; public RpcObject() { } public RpcObject(Class<?> c, String methodName, Object[] args) {
this.c = c;
this.methodName = methodName;
this.args = args;
} public Class<?> getC() {
return c;
} public void setC(Class<?> c) {
this.c = c;
} public String getMethodName() {
return methodName;
} public void setMethodName(String methodName) {
this.methodName = methodName;
} public Object[] getArgs() {
return args;
} public void setArgs(Object[] args) {
this.args = args;
}
}

ConfMonitor

 package com.rpc.server;

 import java.util.HashMap;
import java.util.Map; import com.rpc.service.impl.HelloImpl; /**
* 模拟配置,实际的框架中大部分都是使用xml进行配置的,比如Hessian是配置在web.xml的servlet属性里的
* @author cdwangzijian
*
*/
public class ConfMonitor {
@SuppressWarnings("rawtypes")
public static Map<String, Class> conf = new HashMap<String, Class>(); static {
conf.put("com.rpc.service.IHello", HelloImpl.class);
}
}

RpcThread

 package com.rpc.server;

 import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.Socket; import com.rpc.entity.RpcObject; public class RpcThread extends Thread { private Socket s; public RpcThread(Socket s) {
this.s = s;
} @Override
public void run() { ObjectInputStream is = null;
ObjectOutputStream os = null; try { is = new ObjectInputStream(s.getInputStream()); // 得到远程调用参数,包含了接口名,调用方法,方法参数
RpcObject rpcObject = (RpcObject) is.readObject(); System.out.println("Method:"+rpcObject.getMethodName()); // 构建接口的实现类,然后通过反射调用方法
Object o = getObject(rpcObject.getC());
System.out.println("class:"+rpcObject.getC()); Object reO = executeMethod(o, rpcObject.getMethodName(), rpcObject.getArgs()); // 输出返回值
os = new ObjectOutputStream(s.getOutputStream());
os.writeObject(reO);
os.flush();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally {
try {
if(is!=null){
is.close();
} if(os!=null){
os.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
} /**
* 通过反射技术执行方法,并返回返回值
* @param o
* @param methodName
* @param args
* @return
*/
private Object executeMethod(Object o, String methodName, Object[] args) {
Object objR = null;
Class<?>[] cs = new Class[args.length];
for (int i = 0; i < args.length; i++) {
Object arg = args[i];
cs[i] = arg.getClass();
}
try {
Method m = o.getClass().getMethod(methodName, cs);
objR = m.invoke(o, args);
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return objR;
} /**
* 根据接口名得到实例
* @param c
* @return
*/
private Object getObject(Class<?> c) {
Object o = null;
try { System.out.println("c.getName:"+c.getName()); o = ConfMonitor.conf.get(c.getName()).newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return o;
}
}

StartUp

 package com.rpc.server;

 import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket; /**
* RPC服务器启动
* @author cdwangzijian
*
*/
public class StartUp { public static final int port = 9001; public static void main(String[] args) {
exportRpc();
} /**
* 导出RPC接口
*/
private static void exportRpc() {
try {
ServerSocket ss = new ServerSocket(port);
while(true){
Socket s = ss.accept();
if(s!=null){
new RpcThread(s).start();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

HelloImpl

 package com.rpc.service.impl;

 import com.rpc.service.IHello;

 public class HelloImpl implements IHello {
@Override
public String sayHello(String name) {
return "hello:" + name;
}
}

IHello

 package com.rpc.service;

 public interface IHello {
String sayHello(String name);
}

客户端实现:

 ProxyFactory

 package com.zhy.proxy;

 import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy; public class ProxyFactory { @SuppressWarnings("unchecked")
public static <T> T create(Class<T> c, String ip, int port) { InvocationHandler handler = new RpcProxy(ip, port, c); return (T) Proxy.newProxyInstance(c.getClassLoader(),new Class[] {c},handler);
}
}

RpcProxy

 package com.zhy.proxy;

 import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.net.Socket; import com.rpc.entity.RpcObject; /**
* 客户端接口代理
* 当客户端接口方法被调用的时候,把方法名,方法参数作为参数。
* 传送给远程服务执行,然后获取返回值
* @author cdwangzijian
*
*/
public class RpcProxy implements InvocationHandler, Serializable{ private String ip;
private int port;
private Class<?> c; private static final long serialVersionUID = 1L; public RpcProxy(String ip, int port, Class<?> c) {
this.ip = ip;
this.port = port;
this.c = c;
} /**
* 动态代理类,当调用接口方法的时候转为调用此方法
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args)throws Throwable { // 用作返回值
Object o = null;
// 通过socket调用远程服务
Socket s = new Socket(ip, port); // 组装为一个保留了要调用的类,方法名及参数的对象,然后序列化之后传给远程
RpcObject rpcObject = new RpcObject(c, method.getName(), args); ObjectOutputStream os = null;
ObjectInputStream is = null; try{
os = new ObjectOutputStream(s.getOutputStream());
os.writeObject(rpcObject);
os.flush(); // 从远程得到返回结果
is = new ObjectInputStream(s.getInputStream());
o = is.readObject(); } catch (Exception e) {
e.printStackTrace(); } finally{ if(os!=null){
os.close();
} if(is!=null){
is.close();
} } return o;
} }

RpcClient

 package com.zhy;

 import com.rpc.service.IHello;
import com.zhy.proxy.ProxyFactory; public class RpcClient {
public static void main(String[] args) { String ip = "localhost";
int port = 9001; IHello hello = ProxyFactory.create(IHello.class, ip, port); System.out.println(hello.sayHello("小明")); }
}

输出结果:

Java简单的RPC实现(一)的更多相关文章

  1. Java 简单的rpc 一

    一,简单rpc 是基于Java socket 编程 ServerSocket serverSocket = new ServerSocket(9999); System.out.println(&qu ...

  2. Java 简单的RPC 实现

    借用了网上某大神的例子.... 目录结构是这样的... RpcFramework 主要是两个方法.一个是暴露服务,一个为引用服务.暴露服务的主要作用是声明一个接口的实现类.可以通过socket 远程调 ...

  3. 分布式架构的基石.简单的 RPC 框架实现(JAVA)

    前言 RPC 的全称是 Remote Procedure Call,它是一种进程间通信方式.允许像调用本地服务一样调用远程服务. 学习来源:<分布式系统架构:原理与实践> - 李林锋 1. ...

  4. Java实现简单的RPC框架(美团面试)

    一.RPC简介 RPC,全称为Remote Procedure Call,即远程过程调用,它是一个计算机通信协议.它允许像调用本地服务一样调用远程服务.它可以有不同的实现方式.如RMI(远程方法调用) ...

  5. Java使用Netty实现简单的RPC

    造一个轮子,实现RPC调用 在写了一个Netty实现通信的简单例子后,萌发了自己实现RPC调用的想法,于是就开始进行了Netty-Rpc的工作,实现了一个简单的RPC调用工程. 如果也有兴趣动手造轮子 ...

  6. 最简单的RPC框架实现

    通过java原生的序列化,Socket通信,动态代理和反射机制,实现一个简单的RPC框架,由三部分组成: 1.服务提供者,运行再服务端,负责提供服务接口定义和服务实现类 2.服务发布者,运行再RPC服 ...

  7. Java自带RPC实现,RMI框架入门

    Java自带RPC实现,RMI框架入门 首先RMI(Remote Method Invocation)是Java特有的一种RPC实现,它能够使部署在不同主机上的Java对象进行通信与方法调用,它是一种 ...

  8. 面试题思考:Java RMI与RPC,JMS的比较

    RPC:(Remote Procedure Call)  被设计为在应用程序间通信的平台中立的方式,它不理会操作系统之间以及语言之间的差异. 支持多语言 RMI:(Remote Method Invo ...

  9. 如何实现一个简单的RPC

    在如何给老婆解释什么是RPC中,我们讨论了RPC的实现思路. 那么这一次,就让我们通过代码来实现一个简单的RPC吧! RPC的实现原理 正如上一讲所说,RPC主要是为了解决的两个问题: 解决分布式系统 ...

随机推荐

  1. 序列化Json时遇到的大小写问题及解决方法

    最近在一个webapi2项目中遇到了一个问题:C#编码规范中规定属性的首字母是大写的(大多数公司采用这种编码风格),但是从其它系统中接收到的json对象的属性却是小写的(大多数公司采用这种编码风格), ...

  2. SQL Server Extended Events 进阶 1:从SQL Trace 到Extended Events

    http://www.sqlservercentral.com/articles/Stairway+Series/134869/ SQL server 2008 中引入了Extended Events ...

  3. VS2012 中不能安装ARCGIS 10.0 SDK的解决方法

    问题描述 在ARCGIS 安装SDK时 就会出错   原因是ARCGIS SDK 10.0只能在VS2010中安装,因为我本机是安的VS2012所以安装不成功.     解决方法 一,在注册表中HKE ...

  4. MongoDB Windowns 配置使用

     MongoDB 下载 MongoDB 提供了可用于 32 位和 64 位系统的预编译二进制包,你可以从MongoDB官网下载安装,MongoDB 预编译二进制包下载地址:https://www.mo ...

  5. JWT+Log4net配置与使用

    Log4net的优点        log4net是.Net下一个非常优秀的开源日志记录组件.log4net记录日志的功能非常强大.它可以将日志分不同的等级,以不同的格式,输出到不同的媒介.程序运行过 ...

  6. Disruptor使用简介

    disruptor是lmax公司开发的一款java高性能并发框架,其本质是一种类似队列的实现“生产者—消费者 ”模式的组件. 下面是其示例代码: public class DisruptorServe ...

  7. python 返回数组的索引

    使用python里的index nums = [1, 2, 3, 4, 5, 6, 1, 9] print nums.index(max(nums)) print nums.index(1) 该方法同 ...

  8. for循环、for in整理

    for循环 作用:按照一定的规律,重复去做某件事情,此时我们就需要使用循环来处理了 例子1:倒着输出每一项 <script type="text/javascript"> ...

  9. 关于使用Iscroll.js异步加载数据后不能滑动到最底端的问题解决方案

    关于使用Iscroll.js异步加载数据后不能滑动到最底端,拉到最下边又弹回去的问题困扰了我老半天,相信很多朋友都遇到了.我刚好不小心解决了,和大家分享一下.由于各种忙,下边就直接上代码吧. (前提是 ...

  10. python3 内置函数详解

    内置函数详解 abs(x) 返回数字的绝对值,参数可以是整数或浮点数,如果参数是复数,则返回其大小. # 如果参数是复数,则返回其大小. >>> abs(-25) 25 >&g ...