自定义rpc
一、服务端暴露的接口
package remote.procedure.call.server;
public interface HelloService {
public String sayHi(String name) ;
}
二、服务端功能接口实现类
package remote.procedure.call.server;
public class HelloServiceImpl implements HelloService {
@Override
public String sayHi(String name) {
System.out.println("你是傻逼!!!!!"+name);
return "hi,"+name ;
}
}
三、 服务端注册中心
(一)接口
package remote.procedure.call.server;
public interface Server {
public void start() ;
public void stop();
public void register(Class service,Class serviceImpl);
}
(二)实现类
input.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
四、客户端
package remote.procedure.call.client;
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.InetSocketAddress;
import java.net.Socket;
public class Client {
@SuppressWarnings("unchecked")
public static <T> T getRemoteProxyObj(Class serviceInterface,
InetSocketAddress addr) {
return (T)Proxy.newProxyInstance(serviceInterface.getClassLoader(),
new Class<?>[] {serviceInterface} , new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Socket socket = new Socket();
ObjectOutputStream output = null ;
ObjectInputStream input = null ;
try {
socket.connect(addr);
output =new ObjectOutputStream( socket.getOutputStream()) ;
output.writeUTF(serviceInterface.getName());
output.writeUTF( method.getName() );
output.writeObject( method.getParameterTypes() );
output.writeObject(args);
input = new ObjectInputStream (socket.getInputStream()) ;
return input.readObject() ;
}catch(Exception e) {
e.printStackTrace();
return null ;
}finally {
try {
if(output!=null)output.close();
if(input!=null) input.close() ;
}catch(Exception e) {
e.printStackTrace();
}
}
}
}) ;
}
}
五、 测试类
(一)启动服务端注册中心
package remote.procedure.call.server;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Method;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ServerCenter implements Server {
private static HashMap<String, Class> serviceRegiser = new HashMap<>();
private static int port;
private static ExecutorService executor
= Executors.newFixedThreadPool( Runtime.getRuntime().availableProcessors() ) ;
private static boolean isRunning = false;
public ServerCenter(int port) {
this.port = port;
}
@Override
public void start() {
ServerSocket server = null ;
try {
server = new ServerSocket();
server.bind(new InetSocketAddress(port));
} catch (IOException e1) {
e1.printStackTrace();
}
isRunning = true ;
while(true) {
System.out.println("start server....");
Socket socket = null ;
try {
socket = server.accept();
} catch (IOException e) {
e.printStackTrace();
}
executor.execute(new ServiceTask(socket) );
}
}
@Override
public void stop() {
isRunning = false ;
executor.shutdown();
}
@Override
public void register(Class service, Class serviceImpl) {
serviceRegiser.put(service.getName(), serviceImpl);
}
private static class ServiceTask implements Runnable{
private Socket socket ;
public ServiceTask() {
}
public ServiceTask(Socket socket) {
this.socket = socket ;
}
@Override
public void run() {
ObjectOutputStream output = null;
ObjectInputStream input = null;
try {
input = new ObjectInputStream(socket.getInputStream());
String serviceName = input.readUTF();
String methodName = input.readUTF();
Class[] parameterTypes = (Class[]) input.readObject();
Object[] arguments = (Object[]) input.readObject();
Class ServiceClass = serviceRegiser.get(serviceName);
Method method = ServiceClass.getMethod(methodName, parameterTypes);
System.out.println("调用并执行了服务端方法");
Object result = method.invoke(ServiceClass.newInstance(), arguments);
output = new ObjectOutputStream(socket.getOutputStream());
output.writeObject(result);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (output != null)
output.close();
if (input != null)
input.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
执行结果:
start server....
start server....
调用并执行了服务端方法
你是傻逼!!!!!hellosss
start server....
调用并执行了服务端方法
你是傻逼!!!!!e12e12
(二)测试客户端调用服务
package remote.procedure.call.test;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.InetSocketAddress;
import java.net.Socket;
import remote.procedure.call.client.Client;
public class RPCClientTest {
public static void main(String[] args)
throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException,
SecurityException, IllegalArgumentException, InvocationTargetException, IOException {
InetSocketAddress inetSocketAddress = new InetSocketAddress("127.0.0.1", 9999);
Object remoteProxyObj = Client.getRemoteProxyObj(Class.forName("remote.procedure.call.server.HelloService"),
inetSocketAddress);
Method method = remoteProxyObj.getClass().getMethod("sayHi", String.class);
method.invoke(remoteProxyObj, "hellosss");
Socket socket = new Socket();
socket.connect(inetSocketAddress);
OutputStream outputStream = socket.getOutputStream();
ObjectOutputStream out = new ObjectOutputStream(outputStream);
out.writeUTF("remote.procedure.call.server.HelloService");
out.writeUTF("sayHi");
out.writeObject(new Class[] { String.class });
out.writeObject(new Object[] { "e12e12" });
out.flush();
outputStream.flush();
ObjectInputStream input = new ObjectInputStream(socket.getInputStream());
System.out.println("结果是:"+(Object) input.readObject());
try {
if (socket.isConnected()) {
socket.close();
System.out.println("关闭成功");
}
} catch (Exception e) {
e.printStackTrace();
System.err.println(e.getMessage());
}
}
}
执行结果:
结果是:hi,e12e12
关闭成功