A simple "RPC Framework" code analysis

Source: Internet
Author: User

0, Service Interface definition---Echo.java

/**/Publicinterface  echo {    public  String Echo ( string string);}

One, client code analysis--Implementation class: Mainclient.java

The client implementation includes obtaining a proxy object and invoking the server's service using that proxy object. When you get the proxy object, you need to specify the class that is being proxied (equivalent to the service name provided by the server side), Server Ip,port.

echo echo = Rpc.getproxy (echo.  Class, "127.0.0.1", 20382); System.out.println (Echo.echo ("Hello,hello")); // use a proxy object to invoke the server's service. and output the result

Second, server-side analysis-implementation class: Mainserver.java

The server implementation includes creating a server object, registering the service it can provide, and initiating the process to listen to the client's connection

        New RPC. Rpcserver ();         /*          * After server startup, you need to register the services that the server can provide so that the client uses the name of the service, the         IP of the server, and the port that         the service is running on to invoke the server's service */           server.register (Echo. class, Remoteecho. class); // Name of the registered service        Server.register (Anotherechoservice.  Class, Anotherechoserviceimpl. class );                Server.start (); // Start the server

Third, the server listens to the Client connection analysis----Implementation class: Listener.java

When Server.start () is created, it creates a listener object, which is a thread class that listens to the client connection.

 Public void start () {            System.out.println ("Start Server");                         /*              * When the server starts, it needs listener to listen for the client's request connection             * Listener is a thread that listens to             the connection              */  New Listener (this);              This true ;            Listener.start (); // Listener is a thread class that executes the thread's Run method after start ()        }

In fact, the listener connection is the Java ServerSocket class and the socket class provides the related function only.

/**= server_socket.accept (); // Establish a TCP connection

Four, dynamic proxy object Generation---Rpc.java

The client only needs to write the build proxy object and use the proxy object to invoke the remote service's code. However, the underlying functionality such as: establishing a connection, serialization (also not considered in this case), cross-language invocation (not considered) ... is done by the RPC framework.

When Mainclient statement: Rpc.getproxy (Echo.class, "127.0.0.1", 20382);

/*          * @param class[]{} This parameter declares an interface implemented by dynamically generated proxy objects, that is, the interface type that clazz represents.         * This indicates the generated proxy object, which is an object of the interface type it implements         * so that it can be used to invoke the method defined in the interface it implements         *          * @param handler a handler parameter to be passed when generating a proxy instance object         * This way, when the proxy instance object invokes the method defined in the interface, it is delegated to the Invoke method declared in the Invocationhandler interface         * At this point, the Invocationhandler invoke method will be automatically called          */          = (T) proxy.newproxyinstance (RPC.  Classnew  class[] {clazz}, handler);         return t;

Returns the proxy object and then delegates the third parameter, handler, to automatically execute invoke (), which encapsulates all relevant information about the client invocation into the invocation object (analyzed later). Then execute the 16th line of code to initiate the connection.

1  PublicObject Invoke (Object proxy, Method method, object[] args)throwsThrowable {2Invocation Invo =Newinvocation ();3 invo.setinterfaces (clazz);4                 5                 //use the reflection mechanism to encapsulate the name of the method represented by the Java.lang.reflect.Method in the invocation Invo object6Invo.setmethod (NewOrg.jy.rpc.protocal.Method (Method.getname (), Method.getparametertypes ()));7 invo.setparams (args);8                 9                 /*Ten * When the method name and parameters of the remote server side that need to be called are encapsulated into Invo, the Client object can pass Invo as a parameter to the server. One * Why do we need to do this? The Invoke method of the Invocationhandler is executed automatically, in which it is based on the generated proxy object proxy (the first parameter) A * The implemented interface (specified by the second parameter of Proxy.newproxyinstance ()) allows you to know which methods are defined in this interface - * The second parameter of the Invoke method of Invocationhandler can parse the method name and parameters in the interface . - * Encapsulate them into the invocation Invo object and send Invo as a client.invoke (invo) parameter to the server side the                  */ -Client.invoke (INVO);//invoke first invokes Init to initiate a socket connection, and then sends the INVO to the output stream -                 returnInvo.getresult (); -}

Five, "client stub"--client.java

The most important is its Invoke method (note with Invocationhandler's Invoke () distinction). It is responsible for establishing the connection, opening the input and output streams, and sending byte data to the server.

1      Public voidInvoke (invocation invo)throwsunknownhostexception, IOException, classnotfoundexception {2 init ();3System.out.println ("Write Data");4Oos.writeobject (INVO);//encapsulates the interface, methods, and parameters of the server that the client needs to call to the server5 Oos.flush ();6OIS =NewObjectInputStream (Socket.getinputstream ());//The input stream used to receive the execution results returned from the server7Invocation result =(invocation) ois.readobject ();8Invo.setresult (Result.getresult ());//Save the result to the invocation result object9}

VI, "server Stub"---implementation class: Rpcserver.java

As mentioned above, the server listens to the client connection through listener, when the client connection is established, the Socket client = Server_socket.accept (); No longer blocks, the server calls its call () method to complete the functionality of the client request. That is, the result of the client request is actually generated at the server execution. The returned result is read in the Client.java Invoke () method. Call () Once again uses the Java reflection (line 11th) Reference: Java dynamic agent

1  Public voidCall (invocation invo) {2 System.out.println (Invo.getclass (). GetName ());3Object obj =Serviceengine.get (Invo.getinterfaces (). GetName ());4             if(obj!=NULL) {5                 Try {6Method m =Obj.getclass (). GetMethod (Invo.getmethod (). Getmethodname (), Invo.getmethod (). Getparams ());7                     /*8 * Using the Java reflection mechanism to execute the method represented by Java.lang.reflect.Method9 * @param result: Execution results of the service obtained after executing the actual methodTen                      */ OneObject result =m.invoke (obj, Invo.getparams ()); AInvo.setresult (result);//encapsulates the execution results of a service into a Invo object. In the following code, the object is written to the output stream -}Catch(throwable th) { - th.printstacktrace (); the                 } -}Else { -                 Throw NewIllegalArgumentException ("has no these class"); -             } +}

Seven, "RPC encoding, decoding, definition of protocol"---Invocation.java Method.java

In fact, this is not the kind of practical open source RPC framework, such as the thrift in the code, IDL ... The above two classes are just the implementation of the RPC implementation of the Java Dynamic Agent, it is to encapsulate the method that the client needs to call, and then specify the interface (service) that the generated proxy object needs to implement.

Eight, Summary:

Run Mainserver.java to start the server, and then run Mainclient.java to start a client connection server to see the results of the execution.

When you need to add a new service: Follow these steps: ① defines the service interface and its implementation class, such as: Anotherechoservice.java②: Registers the newly added service in Mainserver.java.

③: Write code in Mainclient.java that obtains the proxy object for the new service and invoke the method declared in the new service interface with the proxy object.

In this way, a new service on the server can be called remotely by the client.

Download the entire source code

Reference article: Java implementation of a custom RPC

A simple "RPC Framework" code analysis

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.