Java实现简单的RPC过程
Java实现简单的RPC过程RPC是远程过程调用(Remote Procedure Call)的缩写,常用于分布式结构系统中。在分布式系统中,一般将系统组件根据需求进行分解,部署在不同服务器上,系统组件间即可通过RPC进行相互连接调用。 设计案例:设计一个计算器,实现计算器内部方法通过远程调用来获得计算结果
Client端构造类:1、面向用户类public class Client { public static void main(String[] args) throws ClassNotFoundException { //创建计算器 Calculator calculator=new CalculatorRemoteImpl(); //调用计算器加方法 int result=calculator.add(52,56); System.out.println(result); } } 2、计算器接口:public interface Calculator { int add(int i,int j); } 3、计算器实现类:实现类内部通过序列化封装对象,发送至Server端,接收Server端执行结果作为方法返回值输出。 import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.net.Socket; import java.net.UnknownHostException; public class CalculatorRemoteImpl implements Calculator{ public int add(int a,int b) { Socket socket = null; ObjectOutputStream objectOutputStream = null; ObjectInputStream objectInputStream = null; try { socket = new Socket("127.0.0.1",9000); //封装计算器操作数,实现可序列化 CalculateRpcRequest calculateRpcRequest = new CalculateRpcRequest(a,b,"add"); //对象输出流,将封装数据的对象序列化写入Socket objectOutputStream = new ObjectOutputStream(socket.getOutputStream()); objectOutputStream.writeObject(calculateRpcRequest); //对象输入流,读入Socket中数据反序列化转换为对象 objectInputStream = new ObjectInputStream(socket.getInputStream()); Object response = null; try { response = objectInputStream.readObject(); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } if(response instanceof Integer) { return (Integer)response; } else { throw new InternalError(); } } catch (UnknownHostException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { if(socket!=null) { try { socket.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if(objectOutputStream!=null) { try { objectOutputStream.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if(objectInputStream!=null) { try { objectInputStream.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } return 0; } } 4、封装操作数和运算方法的序列化对象import java.io.Serializable; public class CalculateRpcRequest implements Serializable { /** * */ private static final long serialVersionUID = 1L; int A; int B; String method; public CalculateRpcRequest(int A,int B,String method) { this.A=A; this.B=B; this.method = method; } } 远程Server端:1、用于反序列化的封装对象注:Client端与Server端的序列化对象必须保持全类名一致,即包名和类名完全相同才能成功转换反序列化对象。 import java.io.Serializable; public class CalculateRpcRequest implements Serializable { /** * */ private static final long serialVersionUID = 1L; int A; int B; String method; public CalculateRpcRequest(int A,String method) { this.A=A; this.B=B; this.method = method; } public int getA() { return A; } public void setA(int a) { A = a; } public int getB() { return B; } public void setB(int b) { B = b; } public String getMethod() { return method; } public void setMethod(String method) { this.method = method; } } 2、远程端计算器接口:public interface Calculator { int add(int i,int j); } 3、远程端计算器实现类:public class CalculatorImpl implements Calculator { @Override public int add(int i,int j) { return i+j; } } 4、远程端接收Client端请求调用本地方法并返回执行结果Server端接收Client端请求,获取封装对象属性值,进行本地方法调用并返回执行结果。 import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.net.ServerSocket; import java.net.Socket; import Test.RPC.consumer.CalculateRpcRequest; public class Server { private static Calculator calculator=new CalculatorImpl(); public static void main(String[] args) { ServerSocket listener = null; ObjectInputStream objectInputStream = null; ObjectOutputStream objectOutputStream = null; try { listener = new ServerSocket(9000); while(true) { //监听连接的TCP Client Socket socket=listener.accept(); //对象输入流,读入Socket中数据反序列化转换为对象 objectInputStream = new ObjectInputStream(socket.getInputStream()); try { Object object = objectInputStream.readObject(); int result=0; if(object instanceof CalculateRpcRequest) { CalculateRpcRequest calculateRpcRequest=(CalculateRpcRequest)object; if("add".equals(calculateRpcRequest.getMethod())) { result=calculator.add(calculateRpcRequest.getA(),calculateRpcRequest.getB()); } else { throw new UnsupportedOperationException(); } } //对象输出流,将封装数据的对象序列化写入Socket objectOutputStream = new ObjectOutputStream(socket.getOutputStream()); objectOutputStream.writeObject(new Integer(result)); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { socket.close(); } } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { if(listener!=null) { try { listener.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if(objectInputStream!=null) { try { objectInputStream.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if(objectOutputStream!=null) { try { objectOutputStream.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } } 总结1、示例通过对象序列化基本实现了RPC过程,对于高级RPC框架的服务注册、负载均衡等机制未进行涉及,本文仅供参考。 2、代码引用:http://bridgeforyou.cn/2018/05/04/How-to-Implement-a-Simple-RPC/ (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |