自定义RPC框架的简单实现
2018-07-22 18:51
363 查看
[code]package com.remote.service; /** * Created by 79782 on 2018/7/22. */ public interface HelloService { public String sayHello(String name); }
[code]package com.remote.service; /** * Created by 79782 on 2018/7/22. */ public class HelloServiceImpl implements HelloService { public String sayHello(String name) { return "hello:"+name; } }
[code]package com.remote.server; /** * Created by 79782 on 2018/7/22. */ public interface Server { public void start(); public void stop(); public void register(Class server ,Class serviceImpl); }
[code]package com.remote.server; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.lang.reflect.Method; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.Socket; import java.util.HashMap; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * Created by 79782 on 2018/7/22. */ public class ServerCenter implements Server { private static HashMap<String,Class> serviceRegiser=new HashMap(); private static int port; private static ExecutorService executor= Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); private static boolean isRunning=false; public static void setPort(int port) { ServerCenter.port = port; } public void start() { isRunning=true; ServerSocket server=null; try { server=new ServerSocket(); server.bind(new InetSocketAddress(9999)); } catch (IOException e) { e.printStackTrace(); } while(true){ try { //等待客户端连接 接受客户端连接及请求 Socket socket = server.accept(); executor.execute(new ServiceTask(socket)); } catch (Exception e) { e.printStackTrace(); } } } public void stop() { isRunning=false; executor.shutdown(); } public void register(Class server ,Class serviceImpl) { serviceRegiser.put(server.getName(),serviceImpl); } private static class ServiceTask implements Runnable{ private Socket socket; public ServiceTask() { } public ServiceTask(Socket socket) { this.socket = socket; } public void run() { ObjectInputStream ois=null; ObjectOutputStream oos =null; try { //Object流有顺序 ois= new ObjectInputStream(socket.getInputStream()); //因为ObjectInputeStream对发送数据的数据严格要求,所以可以一个一个接受 String serviceName=ois.readUTF(); String methodName=ois.readUTF(); Class[] paramType= (Class[]) ois.readObject(); Object[] arguments= (Object[]) ois.readObject(); //根据请求找到请求的接口 Class serviceClass = serviceRegiser.get(serviceName); Method method = serviceClass.getMethod(methodName, paramType); Object result=method.invoke(serviceClass.newInstance(), arguments); oos= new ObjectOutputStream(socket.getOutputStream()); oos.writeObject(result); }catch (Exception e) { e.printStackTrace(); }finally { if(oos!=null){ try { oos.close(); } catch (IOException e) { e.printStackTrace(); } } if(ois!=null){ try { ois.close(); } catch (IOException e) { e.printStackTrace(); } } } } } }
[code]package com.remote.client; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.OutputStream; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.net.InetSocketAddress; import java.net.Socket; /** * Created by 79782 on 2018/7/22. */ public class Client { //获取代表服务端接口的动态代理对象 //serviceName:客户端向服务端请求的接口名 @SuppressWarnings("unchecked") public static <T> T getRemoteProxyObj(final Class serviceInterface, final InetSocketAddress addr){ return (T)Proxy.newProxyInstance(serviceInterface.getClassLoader(), new Class<?>[]{serviceInterface}, new InvocationHandler() { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { ObjectOutputStream oos=null; ObjectInputStream ois=null; try{ Socket socket=new Socket(); socket.connect(addr); oos= new ObjectOutputStream(socket.getOutputStream()); //接口名、接口方法名、方法类型,方法参数、 oos.writeUTF(serviceInterface.getName()); oos.writeUTF(method.getName()); oos.writeObject(method.getParameterTypes()); oos.writeObject(args); //等待服务端处理 //服务端处理返回结果 ois= new ObjectInputStream(socket.getInputStream()); return ois.readObject(); }catch (Exception e){ e.printStackTrace(); return null; }finally { if(ois!=null){ ois.close(); } if(oos!=null){ oos.close(); } } } }); } }
[code]package com.remote.server; import com.remote.service.HelloService; import com.remote.service.HelloServiceImpl; /** * Created by 79782 on 2018/7/22. */ public class ServerMain { /** 服务端将可以提供的接口注册到服务中心 通过map保存key:发布接口的名字,value:接口的实现类 服务端接收客户端请求后,通过请求的接口名在服务中心的map中寻找对应的接口实现类。 解析客户端发送的方法名,接口名,解析完毕后通过反射技术将该方法执行 执行完毕后将结果返回给客户端 */ public static void main(String[] args) { new Thread(new Runnable() { public void run() { Server server=new ServerCenter(); server.register(HelloService.class, HelloServiceImpl.class); server.start(); } }).start(); } }
[code]package com.remote.client; import com.remote.service.HelloService; import java.net.InetSocketAddress; /** * Created by 79782 on 2018/7/22. */ public class ClientMain { public static void main(String[] args) throws ClassNotFoundException { /** * 客户端通过socket请求服务端,并且通过字符串形式将请求的接口名发送给服务端 * 动态代理:发送接口名,方法参数 */ HelloService helloService=Client.getRemoteProxyObj( Class.forName("com.remote.service.HelloService"), new InetSocketAddress("127.0.0.1",9999)); System.out.println(helloService.sayHello("yanfang")); } }
阅读更多
相关文章推荐
- 最简单的RPC框架的实现
- 基于Netty的RPC简单框架实现(四):Netty实现网络传输
- 基于Netty的RPC简单框架实现(一):RPC客户端
- 一个简单的rpc框架的实现
- Java实现简单的RPC框架
- 最简单的RPC框架实现
- Java实现简单的RPC框架
- JAVA通信(2)--实现简单的RPC框架
- Java打造RPC框架(二):11个类实现简单Java RPC
- 【远程调用框架】如何实现一个简单的RPC框架(一)想法与设计
- 分布式学习笔记1通过Java自己实现简单的HTTP RPC框架
- Java实现简单的RPC框架
- 一个简单RPC框架是如何炼成的(IV)——实现RPC消息的编解码
- 基于Netty的RPC简单框架实现(二):RPC服务端
- java实现简单的RPC框架
- 简单的RPC框架的实现
- 【远程调用框架】如何实现一个简单的RPC框架(五)优化三:软负载中心设计与实现
- 自定义基于netty的rpc框架(2)---服务端的实现
- 【远程调用框架】如何实现一个简单的RPC框架(三)优化一:利用动态代理改变用户服务调用方式
- 使用Akka实现一个简单的RPC框架(二)