rpc远程调用的简单实现

rpc实现的技术:反射,jdk动态代理,对象io流,web-socket编程web-socket编程告诉服务端现在用的是哪个接口,服务端根据注册库找到对应的实现类,并且将该实现类通过io返回给消费端消费端只有接口,得到io返回的对象后生成代理对象所以最后调用的是代理对象的方法核心代码:①服务端 ②客户端 具体的项目在附件中①/** * */package rpcDemo.server;import java.io.IOException;import java.io.InputStream;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.io.OutputStream;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.net.ServerSocket;import java.net.Socket;import java.util.concurrent.ConcurrentHashMap;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.atomic.AtomicBoolean;/** * @author chenliang * @date 2017年7月19日 * @version [版本号] */public class RpcServer { private static final ExecutorService threadPool = Executors.newFixedThreadPool(50); //线程池 /** * 服务库 * */ private static ConcurrentHashMap map = new ConcurrentHashMap<>(); //相比于map实现了锁,并且优于hashTable private static AtomicBoolean isRun = new AtomicBoolean(true); //可以保证线程之间的原子性,不会被其他线程打断 public void registerService(Object service){ Class<? extends Object> clazz = service.getClass(); Class<?>[] interfaces = clazz.getInterfaces(); if(interfaces==null){ throw new IllegalArgumentException("服务类必须实现接口"); } Class interfacezz = interfaces[0]; String name = interfacezz.getName(); map.put(name, service); System.out.println(clazz.getName()+"服务注册成功"); } public void startServer(final int port){ try { @SuppressWarnings("resource") ServerSocket serverSocket = new ServerSocket(port); System.out.println("服务启动成功..."); while(isRun.get()){ Socket socket = serverSocket.accept(); threadPool.execute(new SocketTask(socket)); //得到一个client的请求就新开一个线程来处理 } } catch (IOException e) { e.printStackTrace(); } } public void stopServer(){ isRun.set(false) ; threadPool.shutdown() ; } public static final class SocketTask implements Runnable{ private Socket socket; public SocketTask(Socket socket){ this.socket = socket; } @Override public void run() { InputStream in = null; OutputStream out = null; ObjectInputStream objIn = null; ObjectOutputStream objOut = null; try { in = socket.getInputStream(); objIn = new ObjectInputStream(in); String serviceName = objIn.readUTF(); String methodName = objIn.readUTF(); Class<?>[] paramTypes = (Class[]) objIn.readObject() ; //参数类型clazz集合 Object[] paramValues = (Object[]) objIn.readObject() ; //参数值集合 System.out.println("serviceName:" + serviceName + " methodName:" + methodName); Object targetService = map.get(serviceName) ; //从注册的map中得到接口对象,从而调用里面的方法 if(targetService == null){ throw new ClassNotFoundException(serviceName + "服务未找到!") ; } Method method = targetService.getClass().getMethod(methodName, paramTypes); Object result = method.invoke(targetService, paramValues); out = socket.getOutputStream(); objOut = new ObjectOutputStream(out); objOut.writeObject(result); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } finally { try { if(objOut != null){ objOut.close() ; } if(out != null){ out.close() ; } if(objIn != null){ objIn.close() ; } if(in != null){ in.close() ; } } catch (IOException e) { e.printStackTrace(); } } } } }②/** * */package client;import java.io.IOException;import java.io.InputStream;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.Socket;/** * @author chenliang * @date 2017年7月19日 * @version [版本号] */public class ServerClient { @SuppressWarnings("unchecked") public static T getServer(final String host,final int port,final Class serviceInterface){ return (T)Proxy.newProxyInstance(serviceInterface.getClassLoader(),new Class[]{serviceInterface}, new InvocationHandler() { @SuppressWarnings("resource") @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Socket socket = null; InputStream in = null; OutputStream out = null; ObjectInputStream objIn = null; ObjectOutputStream objOut = null; try { socket = new Socket(host, port); out = socket.getOutputStream(); objOut = new ObjectOutputStream(out); objOut.writeUTF(serviceInterface.getName()); objOut.writeUTF(method.getName()); objOut.writeObject(method.getParameterTypes()); objOut.writeObject(args); in = socket.getInputStream(); objIn = new ObjectInputStream(in); return objIn.readObject(); } catch (Exception e) { System.out.println("调用服务异常"); return null; }finally { try { if(objOut != null){ objOut.close() ; } if(out != null){ out.close() ; } if(objIn != null){ objIn.close() ; } if(in != null){ in.close() ; } } catch (IOException e) { e.printStackTrace(); } } } }); } }代码有参考别人的博客,具体哪篇忘记了,搜索到补上
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值