Last night nothing, plus work to use, so began to learn the RPC framework, now write a basic, easy to understand, follow-up to add content.
* * service provider:
**
Service Interface Code:
Package zhm.rpc.server;
Public interface Iserver {public
string TestMethod (string arg);
}
Interface Implementation class:
/** *
Rpcserverimpl.java *
zhm.rpc.server *
October 9, 2017 pm 8:44:06
*
*
* * * Package Zhm.rpc.server;
/**
* @author zhuheming
* Rpcserverimpl *
October 9, 2017 pm 8:44:06/public
class Rpcserverimpl Implements Iserver {/*
(Non-javadoc)
* @see Zhm.rpc.server.iserver#testmethod (java.lang.String) * *
@Override Public
string TestMethod (String arg) {
//TODO auto-generated method stub return
"Hello, "+arg;
}
}"
Reflection class:
It is mainly used to receive the remote call request initiated by the service consumer, and get method and args, that is, methods and parameters, and then execute the method by reflection, return the execution result.
Here the reflection is implemented using the Methodutils tool class in the Commons.lang3 package.
/** * Serverreflect.java * zhu.rpc.reflect * * * * * * October 9, 2017 afternoon 9:24:47 * * * * Package zhu.rpc.reflect;
Import java.io.IOException;
Import Java.io.ObjectInputStream;
Import Java.io.ObjectOutputStream;
Import Java.net.ServerSocket;
Import Java.net.Socket;
Import Org.apache.commons.lang3.reflect.MethodUtils;
/** * @author zhuheming * serverreflect * October 9, 2017 pm 9:24:47/public class Serverreflect implements
Private Object object;
private int port;
Public Serverreflect (Object object,int port) {this.object=object;
This.port=port; }/* (non-javadoc) * @see java.lang.runnable#run () * * * @Override public void Run () {//TODO
auto-generated method Stub//New Connection//socketconnect sc=new socketconnect ();
Socket socket=sc.connect ("127.0.0.1", port);
try {serversocket ss=new serversocket (port);
while (true) {try { Final Socket socket=ss.accept ();
Establish the input ObjectInputStream ois=new ObjectInputStream (Socket.getinputstream ());
try{//Get method name and parameter list String Method=ois.readutf ();
Object[] args= (object[]) ois.readobject ();
System.out.print (method+ "" +args.tostring ());
Reflection gets the result of the corresponding method of the execution of the object Resultobject=methodutils.invokeexactmethod (object, method, args);
ObjectOutputStream oos=new ObjectOutputStream (Socket.getoutputstream ());
try{//Return results oos.writeobject (resultobject);
}catch (Exception e) {oos.writeobject (e);
E.printstacktrace ();
}finally{Oos.close (); The catch (Exception e) {//TODO auto-generated catch block
E.printstacktrace ();
}finally{Ois.close ();
}}catch (Exception e) {e.printstacktrace (); '} ' catch (IOException E1) {//TODO auto-generated catch block E1.printstac
Ktrace ();
}//private static thread Serverthread=new thread ();
public void Waittingserver (class<t> serverclass,int Port)}
Test entrance:
Save trouble by using the 8081 port directly and using a thread to run the call that waits for the service consumption side.
/** * Test.java * zhm.rpc.test * * * * * *
October 9, 2017 afternoon 10:18:33
* * * *
package zhm.rpc.test;
Import Zhm.rpc.server.IServer;
Import Zhm.rpc.server.rpcServerImpl;
Import Zhu.rpc.reflect.ServerReflect;
/**
* @author zhuheming
* Test
* October 9, 2017 afternoon 10:18:33 * * Public
class TestServer {
public static void Main (String args[]) throws interruptedexception{
iserver is=new Rpcserverimpl ();
Thread Serverthread=new Thread (new Serverreflect (is,8081));
Serverthread.start ();
Serverthread.join ();
}
* * service consumer side:
**
Socket connector, which uses a connection interface iconnect, to facilitate the use of multiple connection methods can be abstract
package zhm.rpc.connect;
Import Java.net.Socket; /** * Socket connector * @author zhuheming * socketconnet * September 28, 2017 pm 11:29:24 * * Public class Socketconnect implements IC
Onnect {@Override public sockets connect (String host, int port) {//TODO auto-generated method stub Determines the input parameter if (! "").
Equalsignorecase (host) &&port!=0) {Socket socket=null;
try{socket=new socket (host,port);
}catch (Exception e) {e.getstacktrace ();
} return socket;
}else{return null; } public void Close (Object connectobject) {if (connectobject!=null) {try{S
Ocket socket= (socket) Connectobject;
Socket.close ();
}catch (Exception e) {e.getstacktrace (); }
}
}
}
The dynamic proxy implementation of the service consumer:
The idea is to generate a dynamic proxy class for the Iserver interface of the service provider, and the Invoke method is invoked when the dynamic proxy class executes the interface method that executes the iserver, in the Invoke method, the remote connection consumer provider, The method name and parameters are sent to the service provider, and the service provider returns the execution results.
/** * Cosumeproxy.java * zhm.rpc.proxy * * * * * * * * September 29, 2017 12:03:30 * * * * Package zhm.rpc.proxy;
Import Java.io.ObjectInputStream;
Import Java.io.ObjectOutputStream;
Import Java.lang.reflect.InvocationHandler;
Import Java.lang.reflect.Method;
Import Java.lang.reflect.Proxy;
Import Java.net.Socket;
Import Zhm.rpc.connect.SocketConnect; /** * @author zhuheming * cosumeproxy * September 29, 2017 a.m. 12:03:30/public class Consumeproxy {//Anonymous inner class method implementation needs to be invoked, so host and port need to be final @SuppressWarnings ("unchecked") public static <T> T consume (class<t> interfaceclass,final String host,final int port) {//Invocationhandler an object (implementing an internal method) of an interface first//invocationhandler Invocationhandler
=; Return (T) proxy.newproxyinstance (Interfaceclass.getclassloader (), New class<?>[]{interfaceclass},new
Invocationhandler () {public object Invoke (Object Proxy, Method method, object[] args) throws throwable{ Establish a connection Socketconnect Sc=neW Socketconnect ();
Socket Socket=sc.connect (host, Port);
Send method and Parameter ObjectOutputStream ops=new ObjectOutputStream (Socket.getoutputstream ());
Ops.writeutf (Method.getname ());
Ops.writeobject (args);
Receive return ObjectInputStream ois=new ObjectInputStream (Socket.getinputstream ());
Object Getobject=ois.readobject ();
return getObject;
}
});
return null;
}
}
Service Provider to service interface
Note that the implementation is on the service provider, and the consumer has only the interface
Package zhm.rpc.server;
Public interface Iserver {public
string TestMethod (string arg);
}
Service consumer entrance:
Mister into the proxy class, and then remotely execute the method.
Package zhm.rpc.test;
Import Zhm.rpc.proxy.ConsumeProxy;
Import Zhm.rpc.server.IServer;
The public class Test {
//remote invokes the TestMethod method of the server, the client has only an interface, and there is no method implementation. Public
static void Main (String args[]) throws interruptedexception{
Object obj= consumeproxy.consume ( Iserver.class, "127.0.0.1", 8081);
if (obj!=null) {
System.out.println (Obj.getclass (). Getinterfaces (). toString ());
System.out.println (Obj.tostring ());
System.out.println ("not null!");
else{
System.out.println ("null!");
}
Iserver rpc= (iserver) obj;
for (int i=0;i<100;i++) {
System.out.println (Rpc.testmethod ("" +i));
Thread.Sleep (1000);}}
Okay, the above is the simplest RPC remote execution framework, want to plump up, follow-up also need to consider a lot, such as their own serialization deserialization, soft load balancing, high availability of NIO communication, service of the solution coupled IOC way, as well as service governance, such as ZK Service release.
Keep working on it.