RPC框架几行代码就够了

虽然以前也大概知道rpc的实现原理,也看过部分msgpack的实现,但是对于反射不是很了解。

现在看到一个简单完整的实现,也解决我的以前的另一个疑惑:

http://topic.csdn.net/u/20111028/14/092f98d0-ecdc-48b2-bf8b-317d5071ab6f.html?seed=361547001&r=77648361#r_77648361

不过,还是不明白为什么msgpack只用函数名,没有结合参数列表来识别一个函数,为了和其它语言兼容?

-------------------------------------------------------------------------------------------------------------------------------------------------

from:http://javatar.iteye.com/blog/1123915

因为要给百技上实训课,让新同学们自行实现一个简易RPC框架,在准备PPT时,就想写个示例,发现原来一个RPC框架只要一个类,10来分钟就可以写完了,虽然简陋,也晒晒: 

[java]  view plain  copy
  1. /*  
  2.  * Copyright 2011 Alibaba.com All right reserved. This software is the  
  3.  * confidential and proprietary information of Alibaba.com ("Confidential  
  4.  * Information"). You shall not disclose such Confidential Information and shall  
  5.  * use it only in accordance with the terms of the license agreement you entered  
  6.  * into with Alibaba.com.  
  7.  */    
  8. package com.alibaba.study.rpc.framework;    
  9.     
  10. import java.io.ObjectInputStream;    
  11. import java.io.ObjectOutputStream;    
  12. import java.lang.reflect.InvocationHandler;    
  13. import java.lang.reflect.Method;    
  14. import java.lang.reflect.Proxy;    
  15. import java.net.ServerSocket;    
  16. import java.net.Socket;    
  17.     
  18. /**  
  19.  * RpcFramework  
  20.  *   
  21.  * @author william.liangf  
  22.  */    
  23. public class RpcFramework {    
  24.     
  25.     /**  
  26.      * 暴露服务  
  27.      *   
  28.      * @param service 服务实现  
  29.      * @param port 服务端口  
  30.      * @throws Exception  
  31.      */    
  32.     public static void export(final Object service, int port) throws Exception {    
  33.         if (service == null)    
  34.             throw new IllegalArgumentException("service instance == null");    
  35.         if (port <= 0 || port > 65535)    
  36.             throw new IllegalArgumentException("Invalid port " + port);    
  37.         System.out.println("Export service " + service.getClass().getName() + " on port " + port);    
  38.         ServerSocket server = new ServerSocket(port);    
  39.         for(;;) {    
  40.             try {    
  41.                 final Socket socket = server.accept();    
  42.                 new Thread(new Runnable() {    
  43.                     @Override    
  44.                     public void run() {    
  45.                         try {    
  46.                             try {    
  47.                                 ObjectInputStream input = new ObjectInputStream(socket.getInputStream());    
  48.                                 try {    
  49.                                     String methodName = input.readUTF();    
  50.                                     Class<?>[] parameterTypes = (Class<?>[])input.readObject();    
  51.                                     Object[] arguments = (Object[])input.readObject();    
  52.                                     ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream());    
  53.                                     try {    
  54.                                         Method method = service.getClass().getMethod(methodName, parameterTypes);    
  55.                                         Object result = method.invoke(service, arguments);    
  56.                                         output.writeObject(result);    
  57.                                     } catch (Throwable t) {    
  58.                                         output.writeObject(t);    
  59.                                     } finally {    
  60.                                         output.close();    
  61.                                     }    
  62.                                 } finally {    
  63.                                     input.close();    
  64.                                 }    
  65.                             } finally {    
  66.                                 socket.close();    
  67.                             }    
  68.                         } catch (Exception e) {    
  69.                             e.printStackTrace();    
  70.                         }    
  71.                     }    
  72.                 }).start();    
  73.             } catch (Exception e) {    
  74.                 e.printStackTrace();    
  75.             }    
  76.         }    
  77.     }    
  78.     
  79.     /**  
  80.      * 引用服务  
  81.      *   
  82.      * @param <T> 接口泛型  
  83.      * @param interfaceClass 接口类型  
  84.      * @param host 服务器主机名  
  85.      * @param port 服务器端口  
  86.      * @return 远程服务  
  87.      * @throws Exception  
  88.      */    
  89.     @SuppressWarnings("unchecked")    
  90.     public static <T> T refer(final Class<T> interfaceClass, final String host, final int port) throws Exception {    
  91.         if (interfaceClass == null)    
  92.             throw new IllegalArgumentException("Interface class == null");    
  93.         if (! interfaceClass.isInterface())    
  94.             throw new IllegalArgumentException("The " + interfaceClass.getName() + " must be interface class!");    
  95.         if (host == null || host.length() == 0)    
  96.             throw new IllegalArgumentException("Host == null!");    
  97.         if (port <= 0 || port > 65535)    
  98.             throw new IllegalArgumentException("Invalid port " + port);    
  99.         System.out.println("Get remote service " + interfaceClass.getName() + " from server " + host + ":" + port);    
  100.         return (T) Proxy.newProxyInstance(interfaceClass.getClassLoader(), new Class<?>[] {interfaceClass}, new InvocationHandler() {    
  101.             public Object invoke(Object proxy, Method method, Object[] arguments) throws Throwable {    
  102.                 Socket socket = new Socket(host, port);    
  103.                 try {    
  104.                     ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream());    
  105.                     try {    
  106.                         output.writeUTF(method.getName());    
  107.                         output.writeObject(method.getParameterTypes());    
  108.                         output.writeObject(arguments);    
  109.                         ObjectInputStream input = new ObjectInputStream(socket.getInputStream());    
  110.                         try {    
  111.                             Object result = input.readObject();    
  112.                             if (result instanceof Throwable) {    
  113.                                 throw (Throwable) result;    
  114.                             }    
  115.                             return result;    
  116.                         } finally {    
  117.                             input.close();    
  118.                         }    
  119.                     } finally {    
  120.                         output.close();    
  121.                     }    
  122.                 } finally {    
  123.                     socket.close();    
  124.                 }    
  125.             }    
  126.         });    
  127.     }    
  128.     
  129. }    

用起来也像模像样:

(1) 定义服务接口 

[java]  view plain  copy
  1. /*  
  2.  * Copyright 2011 Alibaba.com All right reserved. This software is the  
  3.  * confidential and proprietary information of Alibaba.com ("Confidential  
  4.  * Information"). You shall not disclose such Confidential Information and shall  
  5.  * use it only in accordance with the terms of the license agreement you entered  
  6.  * into with Alibaba.com.  
  7.  */    
  8. package com.alibaba.study.rpc.test;    
  9.     
  10. /**  
  11.  * HelloService  
  12.  *   
  13.  * @author william.liangf  
  14.  */    
  15. public interface HelloService {    
  16.     
  17.     String hello(String name);    
  18.     
  19. }    

(2) 实现服务  

[java]  view plain  copy
  1. /*  
  2.  * Copyright 2011 Alibaba.com All right reserved. This software is the  
  3.  * confidential and proprietary information of Alibaba.com ("Confidential  
  4.  * Information"). You shall not disclose such Confidential Information and shall  
  5.  * use it only in accordance with the terms of the license agreement you entered  
  6.  * into with Alibaba.com.  
  7.  */    
  8. package com.alibaba.study.rpc.test;    
  9.     
  10. /**  
  11.  * HelloServiceImpl  
  12.  *   
  13.  * @author william.liangf  
  14.  */    
  15. public class HelloServiceImpl implements HelloService {    
  16.     
  17.     public String hello(String name) {    
  18.         return "Hello " + name;    
  19.     }    
  20.     
  21. }    

(3) 暴露服务  

[java]  view plain  copy
  1. /*  
  2.  * Copyright 2011 Alibaba.com All right reserved. This software is the  
  3.  * confidential and proprietary information of Alibaba.com ("Confidential  
  4.  * Information"). You shall not disclose such Confidential Information and shall  
  5.  * use it only in accordance with the terms of the license agreement you entered  
  6.  * into with Alibaba.com.  
  7.  */    
  8. package com.alibaba.study.rpc.test;    
  9.     
  10. import com.alibaba.study.rpc.framework.RpcFramework;    
  11.     
  12. /**  
  13.  * RpcProvider  
  14.  *   
  15.  * @author william.liangf  
  16.  */    
  17. public class RpcProvider {    
  18.     
  19.     public static void main(String[] args) throws Exception {    
  20.         HelloService service = new HelloServiceImpl();    
  21.         RpcFramework.export(service, 1234);    
  22.     }    
  23.     
  24. }    

(4) 引用服务  

[java]  view plain  copy
  1. /*  
  2.  * Copyright 2011 Alibaba.com All right reserved. This software is the  
  3.  * confidential and proprietary information of Alibaba.com ("Confidential  
  4.  * Information"). You shall not disclose such Confidential Information and shall  
  5.  * use it only in accordance with the terms of the license agreement you entered  
  6.  * into with Alibaba.com.  
  7.  */    
  8. package com.alibaba.study.rpc.test;    
  9.     
  10. import com.alibaba.study.rpc.framework.RpcFramework;    
  11.     
  12. /**  
  13.  * RpcConsumer  
  14.  *   
  15.  * @author william.liangf  
  16.  */    
  17. public class RpcConsumer {    
  18.         
  19.     public static void main(String[] args) throws Exception {    
  20.         HelloService service = RpcFramework.refer(HelloService.class"127.0.0.1"1234);    
  21.         for (int i = 0; i < Integer.MAX_VALUE; i ++) {    
  22.             String hello = service.hello("World" + i);    
  23.             System.out.println(hello);    
  24.             Thread.sleep(1000);    
  25.         }    
  26.     }    
  27.         
  28. }    

你可能感兴趣的:(java,rpc)