java achieve RPC

First, the service provider

Engineering battercake-provider, project structure as shown in FIG.

1.1 interface and implementation class to create a "selling pancakes" micro-services

package com.jp.service;

public interface BatterCakeService {
    /**
     * Selling pancakes Service
     */
    public String sellBatterCake(String name);
}
package com.jp.service;

import com.jp.service.BatterCakeService;

/**
 * Selling pancakes Service implementation class
 *
 */
public class BatterCakeServiceImpl implements BatterCakeService {

    public String sellBatterCake (String name) {
         return name + "pancakes, selling particularly well" ;
    }    
}

1.2 RPC framework calls section

The section has two key components: RPC service provider and thread processing class

1) RPC service provider

  1. The need to publish the service is stored in a memory variable serviceList in. ( This example is to sell pancakes service instance object passed )
  2. Start socket, server.accept () method blocks there, listening input
  3. For each request, start a separate thread processing
. 1  Package com.jp.rpc;
 2  
. 3  Import the java.net.ServerSocket;
 . 4  Import the java.net.Socket;
 . 5  Import of java.util.ArrayList;
 . 6  Import java.util.Arrays;
 . 7  Import java.util.List;
 . 8  / ** 
9  * RPC service provider
 10  * 1, will need to publish service is stored in a memory variable serviceList
 11  * 2, start socket, server.accept () method blocks there, listening input
 12  * 3, for each a request to start processing a single thread
 13 is   * / 
14  public  class RpcProvider {
 15      
16      // store a registered service list 
17     Private  static List <Object> serviceList;
 18 is      
. 19      / ** 
20 is       * rpc service release
 21 is       * @param Object provided (sold pancakes) service instance object
 22 is       * @param Port listening on port
 23 is       * @throws Exception
 24       * / 
25      public  static  void Export ( int Port, ... Object Services) throws Exception {
 26 is          serviceList = Arrays.asList (Services);
 27          the ServerSocket Server = new newThe ServerSocket (Port);
 28          the Socket Client = null ;
 29          the while ( to true ) {
 30              // block waiting for input, each will generate a request to a socket object 
31 is              Client = server.accept ();
 32              // every request, processing starts a thread
 33 is              new new the thread ( new new ServerThread ( Client , serviceList )) start ();.
 34 is          }
 35      }
 36 }

2) Threading class

ServerThread ( Socke target , service instances list ) threading class code, ServerThread mainly to do the following steps

  1. Reads the service name sent by the client
  2. Determine whether the service is released
  3. If released, then take the logical reflection, dynamic invocation result is returned
  4. If you do not publish, notice the prompt return
 1 package com.jp.rpc;
 2 
 3 import java.io.IOException;
 4 import java.io.ObjectInputStream;
 5 import java.io.ObjectOutputStream;
 6 import java.lang.reflect.Method;
 7 import java.net.Socket;
 8 import java.util.List;
 9 
10 public class ServerThread implements Runnable {
11 
12     private Socket client = null;
13 
14     private List<Object> serviceList = null;
15 
16     public ServerThread(Socket client, List<Object> service) {
17         this.client = client;
18         this.serviceList = service;
19     }
20 
21     //@Override
22     public void run() {
23         ObjectInputStream input = null;
24         ObjectOutputStream output = null;
25         try {
26             input = new ObjectInputStream(client.getInputStream());
27              the Output = new new ObjectOutputStream (client.getOutputStream ());
 28              // reads the client to access the Service 
29              Class serviceClass = (Class) input.readObject ();
 30              // find the service class instance 
31              Object obj = findService (serviceClass);
 32              IF (obj == null ) {
 33 is                  output.writeObject (serviceClass.getName () + "No service" );
 34 is              } the else {
 35                  // using reflection to invoke the method, returns the result
 36                  @Get request from the request method name and method parameters; with the above-obtained service object instance; reflection method get specific examples; Invoke performed
 37 [                 the try{
38 is                     String methodName =input.readUTF ();
39                     <?> Class [] The parameterTypes = (<?> Class[]) input.readObject ();
40                     Object [] = arguments(Object []) input.readObject ();
41 is                     
42 is                     Method, Method =. obj.getClass () getMethod (methodName, The parameterTypes);  
43 is                     Object Result =Method.invoke (obj, arguments);  
44 is                     output.writeObject (Result); 
45                 }the catch (Throwable t) {
46                     output.writeObject(t);
47                 }
48             }
49         } catch (Exception e) {
50             e.printStackTrace();
51         } finally {
52             try {
53                 client.close();
54                 input.close();
55                 output.close();
56             } catch (IOException e) {
57                 // TODO Auto-generated catch block
58                 e.printStackTrace ();
 59              }
 60          }
 61 is  
62 is      }
 63 is  
64      // to find the service instance of the service list 
65      Private Object findService (serviceClass Class) {
 66          for (Object obj: serviceList) {
 67              Boolean isFather = serviceClass.isAssignableFrom ( obj.getClass ());
 68              IF (isFather) {
 69                  return obj;
 70              }
 71 is          }
 72          return  null ;
 73 is      }
 74  
75 }

1.3 Publishing Service

. 1  Package com.jp.start;
 2  
. 3  Import com.jp.rpc.RpcProvider;
 . 4  Import com.jp.service.BatterCakeService;
 . 5  Import com.jp.service.BatterCakeServiceImpl;
 . 6  
. 7  public  class RpcBootStrap {
 . 8      public  static  void main (String [] args) throws Exception {
 9          // instantiate "selling pancakes," the service implementation class 
10          BatterCakeService batterCakeService = new new BatterCakeServiceImpl ();
 11          // release service selling pancakes: 20006 registered in the port, and the provision of services examples of the incoming 
12         RpcProvider.export(20006,batterCakeService);
13     }
14 }

Second, the service consumer

Consumers engineering battercake-consumer, project structure is shown below

2.1 rpc call part

Divided into two parts: a processor-based proxy (proxy class factory) and the service agent class object (i.e., the front plant returned)

1) proxy class processor (proxy class factory)

Responsible for the production proxy class ( incoming name service (class);? Ip; port )

 1 package com.jp.rpc;
 2 
 3 import java.lang.reflect.Proxy;
 4 
 5 /**
 6  * 用于生产服务代理类
 7  */
 8 public class RpcConsumer {
 9     public static <T> T getService(Class<T> clazz,String ip,int port) {
10         ProxyHandler proxyHandler =new ProxyHandler(ip,port);
11         return (T)Proxy.newProxyInstance(RpcConsumer.class.getClassLoader(), new Class<?>[] {clazz}, proxyHandler);
12     }
13 }

2)服务代理类的处理器该类就是代理类功能的具体实现者,其实就是封装了调用远程服务的过程(封装请求数据发给远端服务提供者,把提供者返回的结果返回

  1. 建立socket连接
  2. 封装请求数据,发送给服务提供者
  3. 返回结果
 1 package com.jp.rpc;
 2 
 3 import java.io.ObjectInputStream;
 4 import java.io.ObjectOutputStream;
 5 import java.lang.reflect.InvocationHandler;
 6 import java.lang.reflect.Method;
 7 import java.net.Socket;
 8 
 9 public class ProxyHandler implements InvocationHandler {
10     
11     private String ip;
12     private int port;
13 
14     public ProxyHandler(String ip, int port) {
15         this.ip = ip;
16         this.port = port;
17     }
18 
19     //@Override
20     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
21         Socket socket = new Socket(this.ip, this.port);
22         ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream());
23         ObjectInputStream input = new ObjectInputStream(socket.getInputStream());
24         try {
25             output.writeObject(proxy.getClass().getInterfaces()[0]);
26             output.writeUTF(method.getName());
27             output.writeObject(method.getParameterTypes());
28             output.writeObject(args);
29             output.flush();
30             Object result = input.readObject();
31             if (result instanceof Throwable) {
32                 throw (Throwable) result;
33             }
34             return result;
35         } finally {
36             socket.shutdownOutput();
37         }
38     }
39 
40 }

2.2 接下来建立一个测试类RpcTest如下

(跑该测试类前,记得运行在battercake-provider端的RpcBootstrap类发布BatterCakeService服务)

 1 package com.jp.start;
 2 
 3 import com.jp.rpc.RpcConsumer;
 4 import com.jp.service.BatterCakeService;
 5 
 6 public class RpcTest {
 7     public static void main(String[] args) {
 8         //生成代理类,三个参数:被代理对象,ip,端口
 9         BatterCakeService batterCakeService = RpcConsumer.getService(BatterCakeService.class, "127.0.0.1", 20006);
10         //调用代理类的方法并获得结果
11         String result = batterCakeService.sellBatterCake("双蛋");
12         System.out.println(result);
13     }
14 }

输出结果如下

 

 

https://blog.csdn.net/wangyunpeng0319/article/details/78651998

https://www.cnblogs.com/rjzheng/category/1205773.html

Guess you like

Origin www.cnblogs.com/xdyixia/p/9227738.html
RPC
RPC