沒想到如此簡單,RPC框架幾行代碼就夠了

10分鐘給你實現一個rpc,就是這麼簡單,來,代碼走起!

<code>/*  * Copyright 2011 Alibaba.com All right reserved. This software is the  * confidential and proprietary information of Alibaba.com ("Confidential  * Information"). You shall not disclose such Confidential Information and shall  * use it only in accordance with the terms of the license agreement you entered  * into with Alibaba.com.  */  package com.alibaba.study.rpc.framework;    import java.io.ObjectInputStream;  import java.io.ObjectOutputStream;  import java.lang.reflect.InvocationHandler;  import java.lang.reflect.Method;  import java.lang.reflect.Proxy;  import java.net.ServerSocket;  import java.net.Socket;    /**  * RpcFramework  *   * @author william.liangf  */  public class RpcFramework {        /**      * 暴露服務      *       * @param service 服務實現      * @param port 服務端口      * @throws Exception      */      public static void export(final Object service, int port) throws Exception {          if (service == null)              throw new IllegalArgumentException("service instance == null");          if (port <= 0 || port > 65535)              throw new IllegalArgumentException("Invalid port " + port);          System.out.println("Export service " + service.getClass().getName() + " on port " + port);          ServerSocket server = new ServerSocket(port);          for(;;) {              try {                  final Socket socket = server.accept();                  new Thread(new Runnable() {                      @Override                      public void run() {                          try {                              try {                                  ObjectInputStream input = new ObjectInputStream(socket.getInputStream());                                  try {                                      String methodName = input.readUTF();                                      Class>[] parameterTypes = (Class>[])input.readObject();                                      Object[] arguments = (Object[])input.readObject();                                      ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream());                                      try {                                          Method method = service.getClass().getMethod(methodName, parameterTypes);                                          Object result = method.invoke(service, arguments);                                          output.writeObject(result);                                      } catch (Throwable t) {                                          output.writeObject(t);                                      } finally {                                          output.close();                                      }                                  } finally {                                      input.close();                                  }                              } finally {                                  socket.close();                              }                          } catch (Exception e) {                              e.printStackTrace();                          }                      }                  }).start();              } catch (Exception e) {                  e.printStackTrace();              }          }      }        /**      * 引用服務      *       * @param  接口泛型      * @param interfaceClass 接口類型      * @param host 服務器主機名      * @param port 服務器端口      * @return 遠程服務      * @throws Exception      */      @SuppressWarnings("unchecked")      public static  T refer(final Class interfaceClass, final String host, final int port) throws Exception {          if (interfaceClass == null)              throw new IllegalArgumentException("Interface class == null");          if (! interfaceClass.isInterface())              throw new IllegalArgumentException("The " + interfaceClass.getName() + " must be interface class!");          if (host == null || host.length() == 0)              throw new IllegalArgumentException("Host == null!");          if (port <= 0 || port > 65535)              throw new IllegalArgumentException("Invalid port " + port);          System.out.println("Get remote service " + interfaceClass.getName() + " from server " + host + ":" + port);          return (T) Proxy.newProxyInstance(interfaceClass.getClassLoader(), new Class>[] {interfaceClass}, new InvocationHandler() {              public Object invoke(Object proxy, Method method, Object[] arguments) throws Throwable {                  Socket socket = new Socket(host, port);                  try {                      ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream());                      try {                          output.writeUTF(method.getName());                          output.writeObject(method.getParameterTypes());                          output.writeObject(arguments);                          ObjectInputStream input = new ObjectInputStream(socket.getInputStream());                          try {                              Object result = input.readObject();                              if (result instanceof Throwable) {                                  throw (Throwable) result;                              }                              return result;                          } finally {                              input.close();                          }                      } finally {                          output.close();                      }                  } finally {                      socket.close();                  }              }          });      }    }  /<code>

定義服務接口

<code>/*  * Copyright 2011 Alibaba.com All right reserved. This software is the  * confidential and proprietary information of Alibaba.com ("Confidential  * Information"). You shall not disclose such Confidential Information and shall  * use it only in accordance with the terms of the license agreement you entered  * into with Alibaba.com.  */  package com.alibaba.study.rpc.test;    /**  * HelloService  *   * @author william.liangf  */  public interface HelloService {        String hello(String name);    }  /<code>

實現服務

<code>/*  * Copyright 2011 Alibaba.com All right reserved. This software is the  * confidential and proprietary information of Alibaba.com ("Confidential  * Information"). You shall not disclose such Confidential Information and shall  * use it only in accordance with the terms of the license agreement you entered  * into with Alibaba.com.  */  package com.alibaba.study.rpc.test;    /**  * HelloServiceImpl  *   * @author william.liangf  */  public class HelloServiceImpl implements HelloService {        public String hello(String name) {          return "Hello " + name;      }    } /<code>

暴露服務

<code>/*  * Copyright 2011 Alibaba.com All right reserved. This software is the  * confidential and proprietary information of Alibaba.com ("Confidential  * Information"). You shall not disclose such Confidential Information and shall  * use it only in accordance with the terms of the license agreement you entered  * into with Alibaba.com.  */  package com.alibaba.study.rpc.test;    import com.alibaba.study.rpc.framework.RpcFramework;    /**  * RpcProvider  *   * @author william.liangf  */  public class RpcProvider {        public static void main(String[] args) throws Exception {          HelloService service = new HelloServiceImpl();          RpcFramework.export(service, 1234);      }    }  /<code>

引用服務

<code>/*  * Copyright 2011 Alibaba.com All right reserved. This software is the  * confidential and proprietary information of Alibaba.com ("Confidential  * Information"). You shall not disclose such Confidential Information and shall  * use it only in accordance with the terms of the license agreement you entered  * into with Alibaba.com.  */  package com.alibaba.study.rpc.test;    import com.alibaba.study.rpc.framework.RpcFramework;    /**  * RpcConsumer  *   * @author william.liangf  */  public class RpcConsumer {            public static void main(String[] args) throws Exception {          HelloService service = RpcFramework.refer(HelloService.class, "127.0.0.1", 1234);          for (int i = 0; i < Integer.MAX_VALUE; i ++) {              String hello = service.hello("World" + i);              System.out.println(hello);              Thread.sleep(1000);          }      }        } /<code>

好了,代碼就在這裡了,是不是非常簡單,大家動手試試吧!


分享到:


相關文章: