• Java通过Socket和动态代理实现简易RPC框架


    本文转自Dubbo作者梁飞大神的CSDN(https://javatar.iteye.com/blog/1123915),代码简洁,五脏俱全.

     1.首先实现RpcFramework,实现服务的暴露与引用功能.

      1 package com.zxd.dubbo.learning.rpc.framework;
      2 
      3 import java.io.IOException;
      4 import java.io.ObjectInputStream;
      5 import java.io.ObjectOutputStream;
      6 import java.lang.reflect.InvocationHandler;
      7 import java.lang.reflect.Method;
      8 import java.lang.reflect.Proxy;
      9 import java.net.ServerSocket;
     10 import java.net.Socket;
     11 
     12 /**
     13  * @Project DubboLearning
     14  * @Package com.zxd.dubbo.learning.rpc.framework
     15  * @Author:zouxiaodong
     16  * @Description:
     17  * @Date:Created in 14:32 2018/10/24.
     18  */
     19 public class RpcFramework {
     20 
     21     /**
     22      * @FileName RpcFramework.java
     23      * @ClassName RpcFramework
     24      * @MethodName export
     25      * @Desc 暴露服务
     26      * @author zouxiaodong
     27      * @date 2018/10/24 15:06
     28      * @Params [service 服务实现, port 服务端口]
     29      * @return void
     30      */
     31     public static void export(final Object service,int port) throws IOException {
     32         if(service == null){
     33             throw new IllegalArgumentException("service instance == null");
     34         }
     35         if(port < 0 || port > 65535){
     36             throw new IllegalArgumentException("Invalid port " + port);
     37         }
     38         System.out.println("Export service :" + service.getClass().getName() + " on port " + port);
     39         ServerSocket serverSocket = new ServerSocket(port);
     40         while (true){
     41             try {
     42                 final Socket socket = serverSocket.accept();
     43                 new Thread(new Runnable() {
     44                     @Override
     45                     public void run() {
     46                         ObjectInputStream input = null;
     47                         ObjectOutputStream output = null;
     48                         try {
     49                             input = new ObjectInputStream(socket.getInputStream());
     50                             String methodName = input.readUTF();
     51                             Class<?>[] parameterTypes = (Class<?>[]) input.readObject();
     52                             Object[] arguments = (Object[]) input.readObject();
     53                             output = new ObjectOutputStream(socket.getOutputStream());
     54                             Method method = service.getClass().getMethod(methodName,parameterTypes);
     55                             Object result = method.invoke(service,arguments);
     56                             output.writeObject(result);
     57                         } catch (Exception e) {
     58                             System.err.println("1."+e.getMessage());
     59                         }finally {
     60                             try {
     61                                 if(output != null){
     62                                     output.close();
     63                                 }
     64                                 if(input != null){
     65                                     input.close();
     66                                 }
     67                                 if(socket != null){
     68                                     socket.close();
     69                                 }
     70                             } catch (IOException e) {
     71                                 System.err.println("2."+e.getMessage());
     72                             }
     73                         }
     74                     }
     75                 }).start();
     76             }catch (Exception e){
     77 
     78             }
     79         }
     80     }
     81 
     82     /**
     83      * @FileName RpcFramework.java
     84      * @ClassName RpcFramework
     85      * @MethodName refer
     86      * @Desc 引用服务
     87      * @author zouxiaodong
     88      * @date 2018/10/24 15:32
     89      * @Params [interfaceClass 接口类型, host 服务器主机名, port 服务器端口]
     90      * @return T 远程服务
     91      */
     92     public static <T> T refer(final Class<T> interfaceClass,final String host,final int port){
     93         if(interfaceClass == null){
     94             throw new IllegalArgumentException("Interface class == null");
     95         }
     96         if(!interfaceClass.isInterface()){
     97             throw new IllegalArgumentException("The " + interfaceClass.getName() + " must be interface class!");
     98         }
     99         if (host == null || host.length() == 0) {
    100             throw new IllegalArgumentException("Host == null!");
    101         }
    102         if (port <= 0 || port > 65535) {
    103             throw new IllegalArgumentException("Invalid port " + port);
    104         }
    105         System.out.println("Get remote service " + interfaceClass.getName() + " from server " + host + ":" + port);
    106         return (T)Proxy.newProxyInstance(interfaceClass.getClassLoader(), new Class<?>[]{interfaceClass}, new InvocationHandler() {
    107             @Override
    108             public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    109                 Socket socket = new Socket(host,port);
    110                 ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream());
    111                 output.writeUTF(method.getName());
    112                 output.writeObject(method.getParameterTypes());
    113                 output.writeObject(args);
    114                 ObjectInputStream input = new ObjectInputStream(socket.getInputStream());
    115                 try {
    116                     Object result = input.readObject();
    117                     if(result instanceof Throwable){
    118                         throw  (Throwable)result;
    119                     }
    120                     return result;
    121                 }finally {
    122                     input.close();
    123                     output.close();
    124                     socket.close();
    125                 }
    126             }
    127         });
    128     }
    129 }

    2.编写接口HelloService.java与实现类HelloServiceImpl.java

     1 package com.zxd.dubbo.learning.rpc.framework;
     2 
     3 /**
     4  * @Project DubboLearning
     5  * @Package com.zxd.dubbo.learning.rpc.framework.api
     6  * @Author:zouxiaodong
     7  * @Description:
     8  * @Date:Created in 15:50 2018/10/24.
     9  */
    10 public interface HelloService {
    11     String hello(String name);
    12 }
     1 package com.zxd.dubbo.learning.rpc.framework;
     2 
     3 
     4 /**
     5  * @Project DubboLearning
     6  * @Package com.zxd.dubbo.learning.rpc.framework.impl
     7  * @Author:zouxiaodong
     8  * @Description:
     9  * @Date:Created in 15:51 2018/10/24.
    10  */
    11 public class HelloServiceImpl implements HelloService {
    12     @Override
    13     public String hello(String name) {
    14         return "Hello "+name;
    15     }
    16 }

    3.编写提供者(暴露服务)

     1 package com.zxd.dubbo.learning.rpc.framework;
     2 
     3 import java.io.IOException;
     4 
     5 /**
     6  * @Project DubboLearning
     7  * @Package com.zxd.dubbo.learning.rpc.framework
     8  * @Author:zouxiaodong
     9  * @Description:
    10  * @Date:Created in 15:54 2018/10/24.
    11  */
    12 public class RpcProvider {
    13     public static void main(String[] args) throws IOException {
    14         HelloService helloService = new HelloServiceImpl();
    15         RpcFramework.export(helloService,12345);
    16     }
    17 }

    4.编写消费者(引用服务)

     1 package com.zxd.dubbo.learning.rpc.framework;
     2 
     3 /**
     4  * @Project DubboLearning
     5  * @Package com.zxd.dubbo.learning.rpc.framework
     6  * @Author:zouxiaodong
     7  * @Description:
     8  * @Date:Created in 15:55 2018/10/24.
     9  */
    10 public class RpcConsumer {
    11     public static void main(String[] args){
    12         HelloService helloService = RpcFramework.refer(HelloService.class,"127.0.0.1",12345);
    13         String result = helloService.hello("CoderZZ");
    14         System.out.println(result);
    15     }
    16 }
  • 相关阅读:
    机器学习之朴素贝叶斯
    机器学习之KNN
    格式化数字
    web.xml中load-on-startup的作用
    ExecutorService线程池
    201404转成 2014.04
    DBCP连接池配置示例
    java 写文本换行
    打印IP 来源
    MySQL分库分表的一些技巧
  • 原文地址:https://www.cnblogs.com/Java-Script/p/11274359.html
Copyright © 2020-2023  润新知