public interface EchoService { String echo(String ping); } public class EchoServiceImpl implements EchoService{ @Override public String echo(String ping) { return ping != null ? ping +"--> i am ok." : " I am ok."; } }
Server Publisher:
/** * Created by hailong on 2016/11/18. * server publisher */ public class RpcExporter { public static Executor executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); public static void exporter(String hostName, int port) throws Exception { // create socket server ServerSocket server = new ServerSocket(); // Bind socket and address port, in RPC service publisher server.bind(new InetSocketAddress(hostName, port)); try { while (true) { // In the thread, receive the request from the client executor.execute(new ExporterTask(server.accept())); } } finally { server.close(); } } // The newly started thread receives the request from the client private static class ExporterTask implements Runnable { Socket client = null; public ExporterTask(Socket client) { this.client = client; } public void run(){ ObjectInputStream input = null; ObjectOutputStream output = null; try{ input = new ObjectInputStream(client.getInputStream()); //Deserialize the code stream sent by the client into an object String interfaceName = input.readUTF(); Class<?> service = Class.forName(interfaceName); String methodName = input.readUTF(); Class<?>[] parameterTypes = (Class<?>[])input.readObject(); Object[] arguments = (Object[])input.readObject(); Method method = service.getMethod(methodName, parameterTypes); // Reflection calls the service implementer to get the execution result. Object result = method.invoke(service.newInstance(), arguments); output = new ObjectOutputStream(client.getOutputStream()); // The execution result is deserialized and sent to the client through the socket. output.writeObject(result); } catch(Exception e) { e.printStackTrace (); } finally { if (output != null) try { output.close(); } catch (IOException e) { e.printStackTrace (); } if (input != null) try { input.close(); } catch (IOException e) { // TODO: handle exception e.printStackTrace (); } if(client != null) { try { client.close(); } catch (IOException e) { e.printStackTrace (); } } } } } }
Client local service:
/** * Created by hailong on 2016/11/18. * Client local service */ public class RpcImporter<S> { public S importer(final Class<?> serviceClass, final InetSocketAddress addr) { // The interface call of the local client is converted into a JDK dynamic proxy, and the remote call is implemented in the dynamic proxy return (S) Proxy.newProxyInstance(serviceClass.getClassLoader(), new Class<?>[] {serviceClass.getInterfaces()[0]}, new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Socket socket = null; ObjectOutputStream output = null; ObjectInputStream input = null; try{ socket = new Socket(); socket.connect(addr); output = new ObjectOutputStream(socket.getOutputStream()); //The RPC service interface value is set to the output stream (EchoServiceImpl.class) output.writeUTF(serviceClass.getName()); //Set the method name echo output.writeUTF(method.getName()); output.writeObject(method.getParameterTypes()); output.writeObject(args); input = new ObjectInputStream(socket.getInputStream()); return input.readObject(); } finally{ if (socket != null) { socket.close(); } if(output != null) { output.close(); } if (input != null) { input.close(); } } } }); } }
Test class:
public class RpcTest { public static void main (String[] args) throws Exception { // RPC server publisher new Thread(new Runnable() { @Override public void run() { try { // Create RPC service publisher RpcExporter.exporter("localhost", 8088); } catch (Exception e) { e.printStackTrace (); } } }).start(); // RPC client RpcImporter<EchoService> importer = new RpcImporter<EchoService>(); // RPC client accesses RPC server interface EchoService echo = importer.importer(EchoServiceImpl.class, new InetSocketAddress("localhost",8088)); System.out.println(echo.echo("Are you ok ?")); } }