RPC框架几行代码就够了
2015-07-03 16:19
357 查看
转自;/article/4348888.html
原理,
服务器启动了一个线程监听 Socket 端口,
有Socket访问了, 反序列化解析出
调用哪个Service 哪个 方法, 以及传入的 参数,
再用Socket 写回去.
客户端 利用 Jdk 的Proxy 生成了一个代理类,
在创建 Proxy 时建立与服务器的Socket连接.
调用 Proxy 的方法时, 向服务器发送数据, 等待结果返回.
核心就是socket和动态代理
原理,
服务器启动了一个线程监听 Socket 端口,
有Socket访问了, 反序列化解析出
调用哪个Service 哪个 方法, 以及传入的 参数,
再用Socket 写回去.
客户端 利用 Jdk 的Proxy 生成了一个代理类,
在创建 Proxy 时建立与服务器的Socket连接.
调用 Proxy 的方法时, 向服务器发送数据, 等待结果返回.
核心就是socket和动态代理
package com.jiepu; 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; /** * RpcFramework * * @author william.liangf */ public class RpcFramework { /** * 暴露服务 * * @param service * 服务实现 * @param port * 服务端口 * @throws Exception */ public static void export(final Object service, int port) throws Exception { if (service == null) throw new IllegalArgumentException("service instance == null"); if (port <= 0 || port > 65535) throw new IllegalArgumentException("Invalid port " + port); System.out.println("Export service " + service.getClass().getName() + " on port " + port); ServerSocket server = new ServerSocket(port); for (;;) { 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(); } } } /** * 引用服务 * * @param <T> * 接口泛型 * @param interfaceClass * 接口类型 * @param host * 服务器主机名 * @param port * 服务器端口 * @return 远程服务 * @throws Exception */ @SuppressWarnings("unchecked") 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.getName() + " must be interface class!"); if (host == null || host.length() == 0) throw new IllegalArgumentException("Host == null!"); if (port <= 0 || port > 65535) throw new IllegalArgumentException("Invalid port " + port); System.out.println("Get remote service " + interfaceClass.getName() + " from server " + host + ":" + port); return (T) Proxy.newProxyInstance(interfaceClass.getClassLoader(), new Class<?>[] { interfaceClass }, new InvocationHandler() { public Object invoke(Object proxy, Method method, Object[] arguments) 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(arguments); 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.jiepu; import com.jiepu.test.HelloService; import com.jiepu.test.HelloServiceImpl; //核心就是socket和动态代理 public class RpcProvider { public static void main(String[] args) throws Exception { HelloService service = new HelloServiceImpl(); RpcFramework.export(service, 1234); } }
package com.jiepu.client; import com.jiepu.RpcFramework; import com.jiepu.test.HelloService; 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); System.out.println(service.getStudent()); Thread.sleep(1000); } } }
package com.jiepu.test; public interface HelloService { String hello(String name); Student getStudent(); }
package com.jiepu.test; public interface HelloService { String hello(String name); Student getStudent(); }
package com.jiepu.test; public class HelloServiceImpl implements HelloService { public String hello(String name) { return "Hello " + name; } @Override public Student getStudent() { return new Student(120, "xxxx", "背景"); } }
相关文章推荐
- Missing artifact javax.jms:jms:jar: Missing artifact com.sun.jdmk Missing artifact com.sun.jmx:jmxri
- php-cp介绍
- c++ primer 学习笔记 1
- 黑马程序员学习日记 Eclipse常用设置
- Weka开发[3]-Evaluation类
- C++写XML
- 谈话Java在ThreadLocal理解类
- web.xml中通过contextConfigLocation的读取spring的配置文件
- Windows下Python添加库(模块)路径
- Java常用正则表达式
- 用phpexcel插件导出excel2003
- eclipse下的jsp:The user operation is waiting for "Building workspace" to complete
- 时滞微分方程的Matlab解法之一dde23
- Matlab如何读入指定文件夹里的所有图片
- PHP函数补完:session_id()
- 循环队列-顺序存储-c语言实现
- Eclipse修改默认Author
- php soap实例讲解
- QT简介
- 使用 Spring Boot 快速构建 Spring 框架应用