• RPC框架几行代码就够了


    转载:http://javatar.iteye.com/blog/1123915#bc2395513

      原作者为梁飞,dubbo的核心成员。本人认为这段代码不长,但是非常利于对RPC的理解,自己受益匪浅。

       java代码:

      

      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 ackage com.alibaba.study.rpc.test;  
     2   
     3 /** 
     4  * HelloService 
     5  *  
     6  * @author william.liangf 
     7  */  
     8 public interface HelloService {  
     9   
    10     String hello(String name);  
    11   
    12 }  

     实现服务 :

     1  package com.alibaba.study.rpc.test;  
     2   
     3 /** 
     4  * HelloServiceImpl 
     5  *  
     6  * @author william.liangf 
     7  */  
     8 public class HelloServiceImpl implements HelloService {  
     9   
    10     public String hello(String name) {  
    11         return "Hello " + name;  
    12     }  
    13   
    14 }  

    服务提供者:

     1 package com.alibaba.study.rpc.test;
     2 
     3 import com.alibaba.study.rpc.framework.RpcFramework;
     4 
     5 /**
     6  * RpcProvider
     7  * 
     8  * @author william.liangf
     9  */
    10 public class RpcProvider {
    11 
    12     public static void main(String[] args) throws Exception {
    13         HelloService service = new HelloServiceImpl();
    14         RpcFramework.export(service, 1234);
    15     }
    16 
    17 }

    服务消费者:

     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 }
    When things go wrong,don't go with them.
  • 相关阅读:
    几种编辑器的markdown-toc生成目录在github上的表现
    Docker 镜像文件的导入和导出
    Python 的 os 与 sys 模块
    IPython 自动重载魔术
    一种新的python局部调试手法
    Python 动态从文件中导入类或函数的方法
    python2中新式类和经典类的多重继承调用顺序
    Python运行目录或压缩文件
    子类化内置类型
    Django 数据库访问性能优化
  • 原文地址:https://www.cnblogs.com/yqy921/p/6274978.html
Copyright © 2020-2023  润新知