rpc详解及实现

本文详细介绍了RPC(远程过程调用)的概念,从原本的本地调用转变为远程调用的背景,以及服务注册中心的引入。通过socket通信,服务端通过反射技术处理客户端的请求,客户端则利用动态代理接收不同接口的响应。文中还阐述了服务端启动、客户端获取服务接口动态代理对象的步骤,并提及了服务端如何处理多个客户端请求的改进方案,即采用线程池。最后,提供了GitHub上的代码示例供参考。
摘要由CSDN通过智能技术生成

定义

一开始AB应用在同一台机器上,是本地调用
在这里插入图片描述
现在分到两个地方上了
在这里插入图片描述
server这边有很多服务A,B,HelloService
在这里插入图片描述
现在要把这些服务放到服务注册中心去,客户端调用的时候直接去跟服务的注册中心去就可以直接调用
注册中心用map来实现
在这里插入图片描述
客户端和服务端通过socket链接

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SJqHqHRQ-1580367610642)(/Users/dylan/Library/Application Support/typora-user-images/image-20200129144921068.png)]

  1. 客户端如果要调用helloService,,而服务端需要通过该字符串"HelloService"解析出该字符串代表的接口的一切信息(通过反射技术)
  2. socket
  3. 服务端需要根据客户端的不同请求,返回不同的借口类型
    客户端就要接受到不同的接口类型(通过动态代理)

按照流程来写代码

1.服务端start()开启服务端服务

服务端首先需要一些内部成员:

public class ServerCenter implements Sever{
   
  //这个用来存放服务名和对应的接口
  private static HashMap<String,Class> serviceRegister = new HashMap<>();
  private static int port;
  public ServerCenter(int port){
   
    this.port = port;
	}
}

然后开启

public void start() throws IOException{
   
  ServerSocket server = new ServerSocket();
  //绑定端口
  server.bind(new InetSocketAddress(port));
  //接受客户端的请求 
  server.accept();
}
2.Client获取代表服务端接口的动态代理对象

服务端要告诉客户端接口的名字和 IP地址端口号()

//参数是:1.客户端请求的服务的接口,socket的地址(即ip+port)
public static <T> T getRemoteProxyObj(Class serviceInterface,InetSocketAddress addr){
   
  /*
  返回一个动态代理即可
  newProxyInstance需要三个参数:
  1.类加载器:需要代理哪个类,比如helloService
  2.接口:需要代理的对象具备哪些功能
  3.一个invocationHandler,采用匿名内部类实现
  */
  return (T)Proxy.newProxyInstance(
    serviceInterface.getClassLoader(),//服务类接口的类加载器
  	new Class<?>[] {
   serviceInterface},//服务类的接口(可能有很多个接口所以使用数组)
    new InvocationHandler(){
   //匿名内部类
      
      @Override
      //只需要实现这一个方法即可
      /*
        	三个参数:
        	1.proxy是代理的对象
        	2.method是需要代理的方法
       		3.args是方法参数列表
      */
      public Object invoke(Object proxy,Method method,Object[] args) throws Throwable{
   
        //1.客户端向服务端发送请求,请求某一个具体的接口
        Socket socket = new Socket();
        socket.connect(addr);//addr = ip + port
        ObjectOutputStream output = newObjectOutputStream(socket.getOutputStream());
        //发送:接口名,方法名,方法参数,参数类型
        output.writeUTF(serviceInterface.getName());
        output.writeUTP(method.getName());
        output.writeObject(method.getParameterTypes());
        output.writeObject(args);
			}
		}
  )
}
服务端接收到客户端连接及请求,处理该请求
public void start() throws IOException{
   
  ServerSocket server = new ServerSocket();
  server.bind(new InetSocketAddress(port));
  Socket socket = server.accept();
  /*----------从这里开始-----------*/
  ObjectInputStream input 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值