RPC介绍
RPC的全称是Remote Procedure Call,即远程过程调用,实现方式有很多,如RMI,WebService等。
RPC的实现包括两方,一方称作服务端(server),一方称作客户端(client)。客户端发送RPC请求到服务端,服务端通过客户端提供的参数执行对应的请求方法,将执行结果返回给客户端,一次RPC调用结束。
基于TCP协议实现的RPC
基于Java的Socket API,我们能够实现一个简单的RPC调用,具体示例如下:包括服务端接口及接口的实现,客户端接口以及远程调用。
代码实现结构图
客户端和服务端接口HelloService
package cn.xiaoyu.rpc.service;
public interface HelloService {
public String sayHello(String name);
}
服务端接口的实现HelloServiceImpl
package cn.xiaoyu.rpc.service;
public class HelloServiceImpl implements HelloService{
@Override
public String sayHello(String name) {
return "Hello " + name;
}
}
服务端主程序MainServer
package cn.xiaoyu.rpc.main;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Method;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import cn.xiaoyu.rpc.service.HelloServiceImpl;
public class MainServer {
public static void main(String[] args) throws Exception {
//将服务接口的示例先初始化,这儿应该还有更好的方法来实现!
HashMap<String, Object> map = new HashMap<>();
map.put("cn.xiaoyu.rpc.service.HelloService",new HelloServiceImpl());
ServerSocket server = new ServerSocket(1234);
while(true){
Socket socket = server.accept();
// 读取传递过来的信息
ObjectInputStream inputStream = new ObjectInputStream(socket.getInputStream());
String interfacename = inputStream.readUTF(); // 接口名称
String methodName = inputStream.readUTF(); // 方法名称
Class<?>[] parameterTypes = (Class<?>[]) inputStream.readObject(); // 参数类型
Object[] params = (Object[]) inputStream.readObject();
// 执行调用过程
Class clazz = Class.forName(interfacename); //获取接口的class
Object service = map.get(interfacename); //获取接口的实现对象
Method method = clazz.getMethod(methodName, parameterTypes); //获取需要的调用的方法
Object result = method.invoke(service, params);
// 将执行结果输出到客户端
ObjectOutputStream outputStream = new ObjectOutputStream(socket.getOutputStream());
outputStream.writeObject(result);
}
}
}
客户端主程序MainClient
package cn.xiaoyu.rpc.main;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Method;
import java.net.Socket;
import cn.xiaoyu.rpc.service.HelloService;
public class MainClient {
public static void main(String[] args) throws Exception{
// 接口名稱
String interfacename = HelloService.class.getName();
// 需要遠程執行的方法
Method method = HelloService.class.getMethod("sayHello",String.class);
//需要传递参数
Object[] params = {"bubu"};
Socket socket = new Socket("127.0.0.1",1234);
//将方法名称和参数传递到服务端
ObjectOutputStream outputStream = new ObjectOutputStream(socket.getOutputStream());
outputStream.writeUTF(interfacename); //调用的接口名称
outputStream.writeUTF(method.getName()); //调用的方法的名称
outputStream.writeObject(method.getParameterTypes());
outputStream.writeObject(params);
//从服务端读取方法的执行结果
ObjectInputStream inputStream = new ObjectInputStream(socket.getInputStream());
Object result = inputStream.readObject();
System.out.println(result);
}
}
#