一个最简单的 RPC 程序.
Service 接口
class="java">
public interface Service {
String sayHello(String name);
String sayJoke();
}
Service 实现类
public class ServiceImpl implements Service {
@Override
public String sayHello(String name) {
return "Hello " + name;
}
@Override
public String sayJoke() {
return "一姐姐半夜打黑车回家,开了后门后,想还是记下车牌吧,于是关门绕到车位看了一眼,结果车开跑了。姐姐心想司机心虚了,还好没坐这车。于是继续等,十分钟后,那黑车又绕回来停在姐姐身边摇下车窗说:你怎么没上来啊,我听关车门以为你上来了,问你去哪儿,一回头没人,这大半夜的吓死我了...(转)";
}
}
Server 端
@SuppressWarnings("rawtypes")
public class Server {
private final Logger logger = LoggerFactory.getLogger(Server.class);
private final Map<Class, Object> serviceMap = new ConcurrentHashMap<>();
public void start(int port) {
ServerRunnable pr = new ServerRunnable(port);
pr.start();
logger.info("Publisher start!");
}
public <T> void publishService(Class<T> service, T impl) {
serviceMap.put(service, impl);
}
private class ServerRunnable extends Thread {
private int port;
private ServerSocket ss = null;
public ServerRunnable(int port) {
this.port = port;
}
@Override
public void run() {
try {
ss = new ServerSocket(port);
} catch (IOException e) {
logger.error("", e);
}
while (true) {
Socket s = null;
try {
logger.info("accept");
s = ss.accept();
} catch (IOException e) {
logger.error("", e);
}
ServerHandler handler = new ServerHandler(s, serviceMap);
handler.start();
}
}
}
private class ServerHandler extends Thread {
private Socket s;
public ServerHandler(Socket s, Map<Class, Object> serviceMap) {
this.s = s;
}
@Override
public void run() {
ObjectInputStream ois = null;
ObjectOutputStream oos = null;
try {
// 主要的逻辑在这了,
ois = new ObjectInputStream(s.getInputStream());
Class service = (Class) ois.readObject();
Object serviceImpl = serviceMap.get(service);
if (serviceImpl != null) {
String methodName = ois.readUTF();
Class[] parameterTypes = (Class[]) ois.readObject();
Object[] args = (Object[]) ois.readObject();
Method method = serviceImpl.getClass().getMethod(methodName, parameterTypes);
Object result = method.invoke(serviceImpl, args);
oos = new ObjectOutputStream(s.getOutputStream());
oos.writeObject(result);
oos.flush();
logger.info("RPC handle finish");
} else {
logger.warn("Service implement not found!");
}
} catch (Exception e) {
logger.error("", e);
} finally {
if (ois != null) {
try {
ois.close();
} catch (IOException e) {
}
}
if (oos != null) {
try {
oos.close();
} catch (IOException e) {
}
}
if (s != null) {
try {
s.close();
} catch (IOException e) {
}
}
}
}
}
public static void main(String[] args) {
Server server = new Server();
server.start(10001);
server.publishService(Service.class, new ServiceImpl());
}
}
Client 端
public class Client {
private static final Logger logger = LoggerFactory.getLogger(Client.class);
@SuppressWarnings("unchecked")
public <T> T getProxy(final String host, final int port, Class<T> service) {
InvocationHandlerImpl<T> handler = new InvocationHandlerImpl<T>(service, host, port);
Object proxy = Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class[] { Service.class }, handler);
return (T) proxy;
}
private class InvocationHandlerImpl<T> implements InvocationHandler {
private Class<T> service;
private String host;
private int port;
public InvocationHandlerImpl(Class<T> service, String host, int port) {
super();
this.service = service;
this.host = host;
this.port = port;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Socket s = null;
ObjectInputStream ois = null;
ObjectOutputStream oos = null;
try {
s = new Socket(host, port);
oos = new ObjectOutputStream(s.getOutputStream());
oos.writeObject(service);
oos.writeUTF(method.getName());
oos.writeObject(method.getParameterTypes());
oos.writeObject(args);
oos.flush();
ois = new ObjectInputStream(s.getInputStream());
return ois.readObject();
} catch (Exception e) {
logger.error("", e);
return null;
} finally {
if (ois != null) {
try {
ois.close();
} catch (IOException e) {
}
}
if (oos != null) {
try {
oos.close();
} catch (IOException e) {
}
}
if (s != null) {
try {
s.close();
} catch (IOException e) {
}
}
}
}
}
public static void main(String[] args) {
Client c = new Client();
Service service = c.getProxy("localhost", 10001, Service.class);
System.out.println( service.sayHello("World"));
System.out.println( service.sayJoke());
}
}