package rpc;

import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * Created by 李恒名 on 2017/8/17.
 */
public class SimpleRpcFramework {


    public static void export(Object service, int port) {
        System.out.println("Export service " + service.getClass().getSimpleName() + " success on port " + port);
        try {
            try (ServerSocket server = new ServerSocket(port)) {
                while (!Thread.currentThread().isInterrupted()) {
                    Socket socket = server.accept();
                    new Thread(() -> {
                        try (ObjectInputStream in = new ObjectInputStream(socket.getInputStream())) {
                            Method method = service.getClass().getMethod(in.readUTF(), (Class<?>[]) in.readObject());
                            Object result = method.invoke(service, (Object[]) in.readObject());
                            try (ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream())) {
                                out.writeObject(result);
                            }
                            System.out.println("Invoke method [" + method.getName() + "()] success, form " + socket.getRemoteSocketAddress());
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }).start();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static <T> T use(Class<T> interfaceClass, String host, int port) {
        System.out.println(String.format("Use remote service [%s] from [%s:%s]", interfaceClass.getSimpleName(), host, port));
        return (T) Proxy.newProxyInstance(interfaceClass.getClassLoader(), new Class<?>[]{interfaceClass}, (proxy, method, args) -> {
            try (Socket socket = new Socket(host, port)) {
                try (ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream())) {
                    out.writeUTF(method.getName());
                    out.writeObject(method.getParameterTypes());
                    out.writeObject(args);
                    try (ObjectInputStream in = new ObjectInputStream(socket.getInputStream())) {
                        return in.readObject();
                    }
                }
            }
        });
    }
}

@@ -271,16 +271,99 @@
 work %7B%0A%0A
+    /**%0A     * %E6%9A%B4%E6%BC%8F%E6%9C%8D%E5%8A%A1%0A     * @param service %E6%9C%8D%E5%8A%A1%E7%9A%84%E5%AE%9E%E7%8E%B0%0A     * @param port %E6%9C%8D%E5%8A%A1%E6%89%80%E5%A4%84%E7%9A%84%E7%AB%AF%E5%8F%A3%E5%8F%B7%0A     */
 %0A    pub
@@ -1688,16 +1688,178 @@
 %0A    %7D%0A%0A
+    /**%0A     * %E4%BD%BF%E7%94%A8%E6%9C%8D%E5%8A%A1%0A     * @param serviceInterface %E8%A6%81%E4%BD%BF%E7%94%A8%E7%9A%84%E6%9C%8D%E5%8A%A1%E7%9A%84%E6%8E%A5%E5%8F%A3%0A     * @param host %E6%9C%8D%E5%8A%A1%E6%89%80%E5%A4%84%E7%9A%84%E4%B8%BB%E6%9C%BA%E5%90%8D%E7%A7%B0%0A     * @param port %E6%9C%8D%E5%8A%A1%E6%89%80%E5%A4%84%E7%9A%84%E7%AB%AF%E5%8F%A3%E5%8F%B7%0A     * @param %3CT%3E%0A     * @return %E6%9C%8D%E5%8A%A1%0A     */%0A
     publ
@@ -1887,25 +1887,32 @@
 lass%3CT%3E 
-i
+serviceI
 nterface
 Class, S
@@ -1903,21 +1903,16 @@
 nterface
-Class
 , String
@@ -2011,25 +2011,32 @@
 s:%25s%5D%22, 
-i
+serviceI
 nterface
 Class.ge
@@ -2023,29 +2023,24 @@
 iceInterface
-Class
 .getSimpleNa
@@ -2101,25 +2101,32 @@
 nstance(
-i
+serviceI
 nterface
 Class.ge
@@ -2117,21 +2117,16 @@
 nterface
-Class
 .getClas
@@ -2155,17 +2155,24 @@
 %3E%5B%5D%7B
-i
+serviceI
 nterface
 Clas
@@ -2167,21 +2167,16 @@
 nterface
-Class
 %7D, (prox

add > 注释