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(); } } } }); } }代码有参考别人的博客,具体哪篇忘记了,搜索到补上
rpc远程调用的简单实现
最新推荐文章于 2024-02-24 22:18:31 发布