RPC服务框架(二) 简单RPC实现
来源:互联网 发布:兔展软件下载 编辑:程序博客网 时间:2024/05/22 06:20
1. 设计思路
基于socket通信:
服务启动时,RPCServer类开启ServerSocket,监听指定端口;接收到连接请求时,开启SocketThread线程处理IO
客户端启动时,ProxyServer连接指定ServerSocket(无服务路由)
编码协议基于json:
请求格式为{"serviceName":,"method":,"param":{}};返回格式为{"code":,"result":{}}
服务定义:
通过接口暴露服务,服务通过集成接口,完成功能实现,同时添加RpcServer注解
服务发布:
服务启动时,加载所有类,扫描类是否包含注解RpcServer,若包含则实例化对象,并放入Map中;
接口调用:
客户端调用服务时,Proxy2Server通过socket发起调用请求,同时接收返回参数;
服务调用:
服务器接收到调用请求时,根据“serviceName”查找服务实现类,“mehod”获得方法,通过反射调用
2.代码实现
RpcServer注解
@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.TYPE)public @interface RpcServer {}
Classutil加载并扫描包含RpcServer注解的类
public class ClassUtil { private static Map<String,Class<?>> serviceMap=new HashMap<String,Class<?>>(); private static Map<String,Object> serviceInstanceMap=new HashMap<String,Object>(); static{ initClassMap(); } public static Map<String,Class<?>> getClassMap(){ return serviceMap; } public static Map<String, Object> getServiceInstanceMap() { return serviceInstanceMap; } private static void initClassMap(){ Set<Class<?>> classSet=new HashSet<Class<?>>(); //扫描获得所有类 getAllClass(classSet); for(Class<?> cls : classSet){ Annotation anno=cls.getAnnotation(RpcServer.class); if(anno != null){ Class<?> [] sc=cls.getInterfaces(); if(sc!=null && sc.length==1){ serviceMap.put(sc[0].getSimpleName(),cls); try { serviceInstanceMap.put(sc[0].getSimpleName(),cls.newInstance()); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } } } }}RpcServer开启ServerSocket监听
public class RPCServer {public void start(){ try { Class.forName("com.luoyu.srpc.util.ClassUtil"); } catch (ClassNotFoundException e) { e.printStackTrace(); } startServer();} private void startServer(){ try { ServerSocket server=new ServerSocket(5555); while(true){ Socket socket=server.accept(); new SocketThread(socket).start(); } } catch (IOException e) { System.out.println("server start fail"); } }}SocketThread处理调用请求
public class SocketThread extends Thread{ private boolean flag=true; private Socket socket; private static BufferedWriter writer; private static BufferedReader reader; public SocketThread(Socket socket) { this.socket = socket; try { writer=new BufferedWriter(new OutputStreamWriter(this.socket.getOutputStream())); reader=new BufferedReader(new InputStreamReader(this.socket.getInputStream())); } catch (IOException e) { e.printStackTrace(); } } @Override public void run() { System.out.println("rcv connect---->"+socket.getRemoteSocketAddress().toString()); while(flag){ JSONObject json=readJson(); if(json.isEmpty()){ continue; } System.out.println("rcv---->"+json.toString()); String serviceName=json.getString("serviceName"); String methodName=json.getString("method"); JSONObject param=json.getJSONObject("param"); JSONObject resp=new JSONObject(); Class<?> cls=ClassUtil.getClassMap().get(serviceName); if(cls==null){ resp.put("code", CodeConstants.NOSERVICE); writeResp(resp); continue; } Method method=null; try { method=cls.getMethod(methodName, JSONObject.class); } catch (NoSuchMethodException e) { resp.put("code",CodeConstants.NOMETHOD); writeResp(resp); continue; } Object instance=ClassUtil.getServiceInstanceMap().get(serviceName); if(instance==null){ resp.put("code", CodeConstants.NOSERVICE); writeResp(resp); continue; } if(method!=null){ try { resp= (JSONObject) method.invoke(instance, param); if(resp==null){ resp=new JSONObject(); } resp.put("code", CodeConstants.OK); writeResp(resp); } catch(Exception e){ resp.put("code",CodeConstants.ERR); writeResp(resp); } } } try { reader.close(); writer.close(); socket.close(); } catch (IOException e1) { } System.out.println("server close socket");}}ProxyServer客户端发起socket连接,发送调用请求
public class Proxy2Sevcer { private static Socket socket; private static BufferedWriter writer; private static BufferedReader reader; public static void connect2Server(){ try { socket=new Socket("127.0.0.1",5555); writer=new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); reader=new BufferedReader(new InputStreamReader(socket.getInputStream())); } catch (IOException e) { System.out.println("connect to server fail"); } } public static void callProxy(String serviceName, String methodName, JSONObject json){ JSONObject req=new JSONObject(); req.put("serviceName",serviceName); req.put("method",methodName); req.put("param",json); JSONObject result=new JSONObject(); try { writer.write(req.toString()); writer.flush(); System.out.println("send---->"+req.toString()); char buf[]=new char[1024]; reader.read(buf); String str=new String(buf); result=JSONObject.parseObject(str); System.out.println("result---->"+str); } catch (IOException e) { System.out.println("client socket close"); try { reader.close(); writer.close(); socket.close(); } catch (IOException e1) { } } }}
3. 测试代码
服务接口
public interface Test { void hello(JSONObject json);}
服务实现类
@RpcServerpublic class TestImpl implements Test{ @Override public void hello(JSONObject json) { System.out.println("hello method invoke---->"+json.toString()); }}
服务调用
public class ClientTest implements Test{ @Override public void hello(JSONObject json) { Proxy2Sevcer.callProxy(Test.class.getSimpleName(),Thread.currentThread().getStackTrace()[1].getMethodName(),json); }}
* 服务调用时,可以通过代理实现,不用在ClientTest写死代码;动态获得serviceName和method
阅读全文
0 0
- RPC服务框架(二) 简单RPC实现
- 使用Akka实现一个简单的RPC框架(二)
- 基于Netty的RPC简单框架实现(二):RPC服务端
- 一起写RPC框架(二十)RPC服务消费者二--服务消费者订阅服务
- 一起写RPC框架(二十二)RPC服务消费者四--服务消费者服务编织
- 简单实现一个rpc框架
- 一起写RPC框架(十)RPC服务提供端二--服务的编织和注册
- 一起写RPC框架(二十一)RPC服务消费者三--服务消费者负载策略
- RPC服务框架(一)
- Java实现一个简单的RPC框架(二) 协议
- 4.RPC框架的简单实现(服务发布-ServiceBean实现)
- 7.RPC框架的简单实现(服务引用-ReferenceBean实现与RMI协议)
- 6.RPC框架的简单实现(服务发布-rmi协议)
- 一起写RPC框架(二十五)RPC测试篇二---服务消费者和服务提供者直连测试
- RPC服务治理框架
- RPC服务框架-dubbox
- 一起写RPC框架(十五)RPC注册中心二--注册中心的基本实现
- 基于Netty的RPC简单框架实现(一):RPC客户端
- 从零基础成为深度学习高手——Ⅰ
- js字符串常用判断方法
- Spring+mybatis分库分表
- LTE信号质量类指标
- 网站开发
- RPC服务框架(二) 简单RPC实现
- POJ
- 用layer-list自定义drawable图形
- 数据库原理 知识点总结
- 盘点 AI 在娱乐行业最佳应用场景
- 用 PreparedStatement 向 SqlServer 中一次性插入多条记录
- 分布式架构--基本思想汇总
- 谈一谈Go的切片Slice的使用方法
- Android开发:在Android Studio中创建menu布局文件