1.RPC简介
RPC的全称是Remote process Call,即远程过程调用。其实现包括客户端和服务端,即服务的调用方与服务的提供方。服务调用方发送RPC请求到服务提供方,服务提供方根据调用方提供的参数执行请求方法,将执行结果返回到调用方,一次
RPC调用完成。
2.代码部分
服务接口类
package com.rpc;
/**
* 服务接口定义
* @Description
* @author LH
* @date 2018年7月5日下午10:47:44
*
*/
public interface EchoService {
String echo(String ping);
}
package com.rpc;
/**
* 服务接口实现
* @Description
* @author LH
* @date 2018年7月5日下午10:48:02
*
*/
public class EchoServiceImpl implements EchoService {
@Override
public String echo(String ping) {
return ping !=null?ping+"--> I am ok ":" I am ok ";
}
}
package com.rpc;
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.concurrent.Executor;
import java.util.concurrent.Executors;
/**
* 服务发布者,运行在服务端,供其他消费者调用
* @Description
* @author LH
* @date 2018年7月5日下午10:44:36
*
*/
public class RpcExporter {
public static Executor executor =Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
/**
* 静态方法
* @param hostName
* @param port
* @throws Exception
*/
public static void exporter(String hostName,int port) throws Exception{
ServerSocket serverSocket = new ServerSocket();
serverSocket.bind(new InetSocketAddress(hostName,port));
try{
while(true){
executor.execute(new ExportTask(serverSocket.accept()));
}
}finally{
serverSocket.close();
}
}
public static class ExportTask implements Runnable{
private Socket client = null;
private ExportTask(Socket socket) {
super();
this.client = socket;
}
public void run() {
ObjectInputStream input=null;
ObjectOutputStream output =null;
try {
//读取服务信息
input = new ObjectInputStream(client.getInputStream());
//接口名称
String interfaceName = input.readUTF();
//方法名称
String methodName = input.readUTF();
//参数类型
Class<?> [] parameterType = (Class<?> []) input.readObject();
//参数对象
Object [] argument = (Object []) input.readObject();
//得到接口的class
Class server = Class.forName(interfaceName);
//取得要调用的方法
Method method = server.getMethod(methodName, parameterType);
//获取服务实现的对象
Object result = method.invoke(server.newInstance(), argument);
//将对象写入到二进制流中
output = new ObjectOutputStream(client.getOutputStream());
output.writeObject(result);
} catch (Exception e) {
e.printStackTrace();
}finally{
if(input!=null){
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(null !=output){
try {
output.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(null != client){
try {
client.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
}
package com.rpc;
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;
/**
* 服务代理类,运行在客户端,通过代理调用远程服务提供者,将结果进行封装返回给本地消费者
* @Description
* @author LH
* @date 2018年7月5日下午10:45:02
*
* @param <S>
*/
public class RpcImporter<S> {
@SuppressWarnings("unchecked")
public S importr(final Class<?> serverClass,final InetSocketAddress address){
return (S) Proxy.newProxyInstance(serverClass.getClassLoader(), new Class<?>[]{serverClass.getInterfaces()[0]},
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Socket socket = null;
ObjectOutputStream objectOutputStream = null;
ObjectInputStream objectInputStream = null;
try {
//socket连接
socket=new Socket();
socket.connect(address);
objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
//将方法名称和参数传递到远端
objectOutputStream.writeUTF(serverClass.getName());//写入接口名称
objectOutputStream.writeUTF(method.getName());//写入方法名称
objectOutputStream.writeObject(method.getParameterTypes());//写入参数类型
objectOutputStream.writeObject(args);//写入参数
//从远端获取方法执行的结果
objectInputStream = new ObjectInputStream(socket.getInputStream());
return objectInputStream.readObject();
} finally{
if(null !=socket){
socket.close();
}
if(null !=objectOutputStream){
objectInputStream.close();
}
if(null !=objectInputStream){
objectInputStream.close();
}
}
}
});
}
}
package com.rpc;
import java.net.InetSocketAddress;
public class TestRpc {
public static void main(String[] args) {
//创建一个异步发布服务端的线程,用于接收RPC客户端的请求
new Thread(new Runnable() {
@Override
public void run() {
try {
RpcExporter.exporter("localhost", 8080);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
).start();
//创建客户端代理类,构造RPC请求参数,发起RPC请求
RpcImporter<EchoService> importer = new RpcImporter<EchoService>();
EchoService echoService = importer.importr(EchoServiceImpl.class, new InetSocketAddress("localhost",8080));
System.out.println(echoService.echo("Are you ok ?"));
}
}
3.测试结果