zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    PHP保留小数的相关方法
    ASP.NET Core MVC 之过滤器(Filter)
    ASP.NET Core MVC 之控制器(Controller)
    ASP.NET Core MVC 之视图组件(View Component)
    ASP.NET Core MVC 之局部视图(Partial Views)
    标签助手(TagHelper)
    ASP.NET Core MVC 之布局(Layout)
    ASP.NET Core MVC 之视图(Views)
    ASP.NET Core MVC 之模型(Model)
    九卷读书:淘宝从小到大的发展 -重读《淘宝技术这十年》
  • 原文地址:https://www.cnblogs.com/Java-Script/p/11274359.html
Copyright © 2011-2022 走看看