一个简单的RPC框架
来源:互联网 发布:开淘宝店进货后如何卖 编辑:程序博客网 时间:2024/05/16 05:40
一个简单的RPC框架
实现原理:动态代理 + socket
框架代码:
package com.yunsheng.rpc.framework;import java.io.IOException;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;public class RpcFramework { /** * 对外暴露服务 * * @author <a href="mailto:shengyun@taobao.com">shengyun</a> * @since 2016年9月1日 * @param service * @param port * @throws Exception */ public static void export(final Object service, int port) throws Exception { if (null == service) { throw new IllegalArgumentException("service is null"); } if (port < 0 || port > 65535) { throw new IllegalArgumentException("Invalid port:" + port); } System.out.println("Export service:" + service.getClass().getName() + " on port :" + port); ServerSocket serverSocket = new ServerSocket(port); for (;;) { // 匿名内部类只能引用外部的final变量 final Socket socket = serverSocket.accept(); new Thread(new Runnable() { @Override public void run() { ObjectInputStream ois = null; try { ois = new ObjectInputStream(socket.getInputStream()); try { // 拿到入参 String methodName = ois.readUTF(); Class<?>[] parameterTypes = (Class<?>[]) ois.readObject(); Object[] arguments = (Object[]) ois.readObject(); ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream()); try { // 反射调用 Method method = service.getClass().getMethod(methodName, parameterTypes); Object result = method.invoke(service, arguments); oos.writeObject(result); } catch (Exception e) { oos.writeObject(e); } finally { oos.close(); } } catch (ClassNotFoundException e) { e.printStackTrace(); } } catch (IOException e) { e.printStackTrace(); } finally { if (null != ois) { try { ois.close(); } catch (IOException e) { e.printStackTrace(); } } try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } } }).start(); } } /** * 引用服务 * * @author <a href="mailto:shengyun@taobao.com">shengyun</a> * @since 2016年9月1日 * @param interfaceName * @param host * @param port * @return * @throws Exception */ public static <T> T refer(final Class<T> interfaceClass, final String host, final int port) throws Exception { if (null == interfaceClass) { throw new Exception("interfaceClass can not be null"); } if (!interfaceClass.isInterface()) { throw new Exception(interfaceClass.getName() + " is not interface"); } if (null == host || host.length() == 0) { throw new Exception("host is null"); } if (port < 0 || port > 65535) { throw new Exception("invalid port"); } System.out.println("Get remote service " + interfaceClass.getName() + "from: " + host + " " + port); // 根据传入的接口生成动态代理类 Object instance = 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 oos = new ObjectOutputStream(socket.getOutputStream()); // 两边参数的读写必须匹配 oos.writeUTF(method.getName()); oos.writeObject(method.getParameterTypes()); oos.writeObject(args); // 一般的动态代理代码中,我们会在invoke里调用真实对象。 // 通过socket传递参数去执行,拿到结果 // 这就是一个简单的rpc实现 ObjectInputStream ois = new ObjectInputStream(socket.getInputStream()); try { Object result = ois.readObject(); if (result instanceof Throwable) { throw (Throwable) result; } return result; } finally { ois.close(); oos.close(); } } finally { socket.close(); } } }); return (T) instance; }}
测试代码:
package com.yunsheng.rpc.framework.test;public interface HelloService { String Hello(String name);}
package com.yunsheng.rpc.framework.test;public class HelloServiceImpl implements HelloService { @Override public String Hello(String name) { return "Hello " + name; }}
package com.yunsheng.rpc.framework.test;import com.yunsheng.rpc.framework.RpcFramework;public class RpcProvider { public static void main(String[] args) throws Exception { HelloService service = new HelloServiceImpl(); RpcFramework.export(service, 1234); }}
package com.yunsheng.rpc.framework.test;import com.yunsheng.rpc.framework.RpcFramework;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<10 ;i++) { String result = service.Hello("yunsheng "+ i); System.out.println(result); Thread.sleep(1000); } }}
0 0
- 一个简单的RPC框架
- 一个简单的rpc框架的实现
- 一个简单的rpc框架的实现
- 自己实现一个简单的RPC框架
- 如何实现一个简单的rpc框架
- 简单实现一个rpc框架
- php实现的一个简单json rpc框架实例
- 一个简单的rpc框架实现(待连载优化)
- 一个简单的rpc框架实现(一)
- Java实现一个简单的RPC框架(一) 本地调用
- Java实现一个简单的RPC框架(二) 协议
- Java实现一个简单的RPC框架(六) 注册机制
- 从头创建一个简单的RPC服务框架
- 小司机带你撸一个简单的RPC框架
- 使用Akka实现一个简单的RPC框架(一)
- 使用Akka实现一个简单的RPC框架(二)
- 一个简单RPC框架是如何炼成的(II)——制定RPC消息
- 一种简单的RPC框架
- 占位
- jQuery:选择与方法
- 数据库单点与Nginx单点提高可用性
- 从B树、B+树、B*树谈到R 树
- string转wstring,wstring转string
- 一个简单的RPC框架
- leetcode:bits:Power of Four(342)
- hdu2047
- java synchronized详解
- 创建自己的maven模版【六】
- 高级软件工程师之路-内存
- @Value注解读取.properties配置内容
- 安装编译好的Android镜像到模拟器上 (android 7.0)
- P1784 数字统计