Netty implementation of simple RPC implementation

Source: Internet
Author: User

The so-called RPC is a remote method call, or simply by mq,tcp,http or the network protocol you write to transmit what I want to call the other side of the interface, the other side processing and then return the results to me. That's a simple process.

At runtime, a client-to-server RPC call, with an internal operation of roughly 10 steps, is as follows:
1 . Calling client handle; executing transfer parameters
2. call the Local system kernel to send network messages
3. Message delivery to remote host
4. The server handle gets the message and obtains the parameter
5. Perform remote procedures
6 . The execution process returns the result to the server handle
7, the server handle returns the result, call the remote system kernel
8. The message is returned to the local host
9. client handle receives message from kernel
The customer receives the data returned by the handle

Before an article simple RPC socket implementation we through the socket communication implementation of a simple RPC call, next we implement a simple RPC call process based on Netty, of course, there are many imperfect places, only for reference to learn RPC use.

First, define the entity class for message passing

public class ClassInfo implements Serializable {private static final long Serialversionuid = -8970942815543515064l;privat E string classname;//class name private String methodname;//function name private class<?>[] types;//parameter type  private object[] objects;//parameter list public  String GetClassName () {return className;} public void Setclassname (String className) {this.classname = ClassName;} Public String Getmethodname () {return methodName;} public void Setmethodname (String methodName) {this.methodname = MethodName;} Public class<?>[] GetTypes () {return types;} public void Settypes (class<?>[] types) {this.types = types;} Public object[] GetObjects () {return objects;} public void SetObjects (object[] objects) {this.objects = objects;}}
Second, create the service side of the Netty operation, and the specific operation

(1) Service side

public class Rpcserver {private int port;public rpcserver (int port) {this.port = port;} public void Start () {Eventloopgroup bossgroup = new Nioeventloopgroup (); Eventloopgroup Workergroup = new Nioeventloopgroup (); try {serverbootstrap serverbootstrap = new Serverbootstrap (). Group (Bossgroup, Workergroup). Channel (Nioserversocketchannel.class). LocalAddress (Port). Childhandler (New                    Channelinitializer<socketchannel> () {@Overrideprotected void Initchannel (Socketchannel ch) throws Exception {                       Channelpipeline pipeline = Ch.pipeline ();                          Pipeline.addlast (New Lengthfieldbasedframedecoder (Integer.max_value, 0, 4, 0, 4));                          Pipeline.addlast (New Lengthfieldprepender (4));                            Pipeline.addlast ("encoder", New Objectencoder ());                          Pipeline.addlast ("Decoder", New Objectdecoder (Integer.max_value, classresolvers.cachedisabled (null))); Pipeline.addlast (New Invokerhandler ()); }}). Option (Channeloption.so_backlog, $). Childoption (Channeloption.so_keepalive, true);            Channelfuture future = Serverbootstrap.bind (port). sync ();          System.out.println ("Server start listen at" + port);  Future.channel (). Closefuture (). sync ();           } catch (Exception e) {bossgroup.shutdowngracefully (); Workergroup.shutdowngracefully ();}}          public static void Main (string[] args) throws Exception {int port;          if (Args.length > 0) {port = Integer.parseint (Args[0]);          } else {port = 8080;      } new Rpcserver (port). Start (); }  }
(2) service-side operation, by the server we see the specific data transmission operation is serialized, the specific operation or relatively simple, is to obtain the information sent over, so that you can get the class name through reflection, according to the function name and parameter values, perform specific operations, the execution results sent to the client.

public class Invokerhandler extends Channelinboundhandleradapter {public static concurrenthashmap<string, Object > classmap = new concurrenthashmap<string,object> (), @Override public void Channelread (Channelhandlercontext        CTX, Object msg) throws Exception {ClassInfo ClassInfo = (classinfo) msg; Object Claszz = null;if (!classmap.containskey (Classinfo.getclassname ())) {try {claszz = Class.forName ( Classinfo.getclassname ()). newinstance (); Classmap.put (Classinfo.getclassname (), CLASZZ);} catch (Instantiationexception | illegalaccessexception | ClassNotFoundException e) {e.printstacktrace ();}} else {claszz = Classmap.get (Classinfo.getclassname ());}          method = Claszz.getclass (). GetMethod (Classinfo.getmethodname (), classinfo.gettypes ());         Object result = Method.invoke (Claszz, classinfo.getobjects ());        Ctx.write (result);          Ctx.flush ();    Ctx.close (); } @Override public void Exceptioncaught (Channelhandlercontext ctx, throwable cause) throws Exception {cause.printstacktrace ();  Ctx.close (); }  }
Third, the client, through the proxy mechanism to trigger the remote call

(1) The client, when executing a specific function, invokes a remote operation that sends the class, function, and parameter information of the specific operation to the server

public class RpcProxy {@SuppressWarnings ("unchecked") public static <T> T Create (Object target) {return (T) proxy.ne Wproxyinstance (Target.getclass (). getClassLoader (), Target.getclass (). Getinterfaces (), new Invocationhandler () {@ Overridepublic object Invoke (Object proxy, Method method, object[] args) throws Throwable {ClassInfo ClassInfo = new ClassI NFO (); Classinfo.setclassname (Target.getclass (). GetName ()); Classinfo.setmethodname (Method.getname ()); Classinfo.setobjects (args); Classinfo.settypes (Method.getparametertypes ());        Resulthandler Resulthandler = new Resulthandler ();          Eventloopgroup Group = new Nioeventloopgroup ();              try {Bootstrap b = new Bootstrap ();               B.group (Group). Channel (niosocketchannel.class). Option (Channeloption.tcp_nodelay, True) . Handler (new channelinitializer<socketchannel> () {@Override public voi D initchannel (Socketchannel ch) throws Exception {                  Channelpipeline pipeline = Ch.pipeline ();                               Pipeline.addlast ("Framedecoder", New Lengthfieldbasedframedecoder (Integer.max_value, 0, 4, 0, 4));                               Pipeline.addlast ("Frameencoder", New Lengthfieldprepender (4));                                 Pipeline.addlast ("encoder", New Objectencoder ());                               Pipeline.addlast ("Decoder", New Objectdecoder (Integer.max_value, classresolvers.cachedisabled (null)));                 Pipeline.addlast ("handler", Resulthandler);                }               });              Channelfuture future = B.connect ("localhost", 8080). sync ();            Future.channel (). Writeandflush (ClassInfo). sync ();          Future.channel (). Closefuture (). sync ();          } finally {group.shutdowngracefully (); } return Resulthandler.getresponse ();}});}}
(2) Gets the result value returned by the remote call
public class Resulthandler extends Channelinboundhandleradapter {private Object response;          Public Object GetResponse () {      return response;  }      @Override public      void Channelread (Channelhandlercontext ctx, Object msg) throws Exception {          response=msg;          SYSTEM.OUT.PRINTLN ("Client received the message returned by the server:" + msg);      }            @Override public      void Exceptioncaught (Channelhandlercontext ctx, Throwable cause) throws Exception {          SYSTEM.OUT.PRINTLN ("Client exception is General");      }  }


IV. interfaces, implementation classes, and main operations

Interface:

Public interface Hellorpc {string Hello (string name);}

Implementation class:

public class Hellorpcimpl implements HELLORPC {@Overridepublic string hello (string name) {return "Hello" +name;}}


Main operation:

public class Main {public static void main (String [] args) {Hellorpc hellorpc = new Hellorpcimpl (); hellorpc = Rpcproxy.crea Te (HELLORPC); System.err.println (Hellorpc.hello ("RPC"));}}


Full Code address GitHub

Netty implementation of simple RPC implementation

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.