package com.dounine.corgi.rpc.serialize.rmi; import com.dounine.corgi.exception.RPCException; import com.dounine.corgi.exception.SerException; import com.dounine.corgi.spring.ApplicationContext; import com.dounine.corgi.rpc.spring.annotation.Service; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.Socket; import java.util.Map; import java.util.Optional; /** * Created by huanghuanlai on 16/9/26. */ public class RpcServer implements Runnable, IServer { private static final Logger LOGGER = LoggerFactory.getLogger(RpcServer.class); private Socket socket; public RpcServer(Socket socket) { this.socket = socket; } @Override public void run() { push(); } @Override public void push() { checkSpringContext(); ObjectInputStream ois = null; ObjectOutputStream oos = null; Throwable exception = null; try { oos = new ObjectOutputStream(socket.getOutputStream()); ois = new ObjectInputStream(socket.getInputStream()); String methodName = ois.readUTF(); String version = ois.readUTF(); Class<?> clazz = (Class<?>) ois.readObject(); Class<?>[] paramterTypes = (Class<?>[]) ois.readObject(); Object[] args = (Object[]) ois.readObject(); Method method = clazz.getMethod(methodName, paramterTypes); Map obs = ApplicationContext.getContext().getBeansOfType(clazz); Optional<Object> oo = obs.values().stream().filter(o -> o.getClass().getAnnotation(Service.class).version().equals(version)).findFirst(); if (!oo.isPresent() && obs.values().size() == 0) { throw new RPCException("class not found."); } else if (!oo.isPresent() && obs.values().size() > 0) { throw new RPCException("class version [ " + version + " ] not found."); } Object result = method.invoke(oo.get(), args); oos.writeObject(null);//write null exception oos.writeObject(result);//write metod invoke result LOGGER.info("CORGI [ " + socket.getRemoteSocketAddress() + " ] client service finish."); } catch (IOException e) { exception = e; } catch (ClassNotFoundException e) { exception = e; } catch (InvocationTargetException e) { if (e.getCause() instanceof SerException) { exception = e.getCause(); } else { exception = e; } } catch (IllegalAccessException e) { exception = e; } catch (NoSuchMethodException e) { e.printStackTrace(); } finally { if (null != exception) { try { oos.writeObject(exception); } catch (IOException e) { e.printStackTrace(); } } if (null != ois) { try { ois.close(); } catch (IOException e) { e.printStackTrace(); } } if (null != oos) { try { oos.close(); } catch (IOException e) { e.printStackTrace(); } } if (null != socket) { if (socket.isConnected()) { try { socket.close(); LOGGER.info("CORGI [ " + socket.getRemoteSocketAddress() + " ] client connect closed.\n"); } catch (IOException e) { e.printStackTrace(); } } } } } public void checkSpringContext() { if (null == ApplicationContext.getContext()) { throw new RPCException("CORGI rpc spring context not null."); } } }