首页 > 其他分享 >230104_50_RPC底层原理

230104_50_RPC底层原理

时间:2023-01-05 00:00:11浏览次数:50  
标签:java bill 50 230104 RPC oos new import com

  • 上述Stud中,有一个参数,writeInt(123),传的都是123这个具体的值,如果接口中暴露了其他的方法,其他方法需要出入的参数不同,就需要对此进行进一步优化。要实现,无论有多少个方法,都用一个处理器进行处理。
  • Stub优化:如果调用那个方法,就将这个方法传入过来,获取这个方法的名字,类型,参数,将这些传给服务端。
package com.bill.rpc04;

import com.bill.rpc.common.IUserService;
import com.bill.rpc.common.User;

import java.io.DataInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.net.Socket;

/**
 * @Auther: wangchunwen
 * @Date: 2023/1/4 - 01 - 04 - 23:30
 * @Description: com.bill.rpc04
 * @version: 1.0
 */
public class Stub {
    public static IUserService getStub(){
        InvocationHandler h = new InvocationHandler() {
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                Socket s = new Socket("127.0.0.1",8888);

                ObjectOutputStream oos = new ObjectOutputStream(s.getOutputStream());

                String methodName = method.getName();
                Class[] parametersTypes = method.getParameterTypes();
                oos.writeUTF(methodName);
                oos.writeObject(parametersTypes);
                oos.writeObject(args);

                DataInputStream dis = new DataInputStream(s.getInputStream());
                int id = dis.readInt();
                String name = dis.readUTF();
                User user = new User(id,name);

                oos.close();
                s.close();
                return user;

            }
        };
        Object o = Proxy.newProxyInstance(IUserService.class.getClassLoader(),new Class[] {IUserService.class},h);
        System.out.println(o.getClass().getName());
        System.out.println(o.getClass().getInterfaces()[0]);
        return (IUserService)o;
    }
}
  • server优化:服务端通过接收客户端传过来的方法名,类型,参数确定调用的是哪个方法,这样就实现了可以调用一个接口的任意方法。
package com.bill.rpc04;

import com.bill.rpc.common.IUserService;
import com.bill.rpc.common.User;
import com.bill.rpc01.UserServiceImpl;

import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * @Auther: wangchunwen
 * @Date: 2023/1/1 - 01 - 01 - 22:39
 * @Description: com.bill.rpc01
 * @version: 1.0
 */
public class Server {
    private static boolean running = true;

    public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException {
        ServerSocket ss = new ServerSocket(8888);
        while (running){
            Socket s = ss.accept();
            process(s);
            s.close();
        }
        ss.close();
    }

    private static void process(Socket s) throws IOException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        InputStream in = s.getInputStream();
        OutputStream out = s.getOutputStream();
        ObjectInputStream oos = new ObjectInputStream(in);
        DataOutputStream dos = new DataOutputStream(out);
        
        String methodName = oos.readUTF();
        Class[] parameterTypes = (Class[]) oos.readObject();
        Object[] args = (Object[]) oos.readObject();
        
        IUserService service = new UserServiceImpl();
        Method method = service.getClass().getMethod(methodName,parameterTypes);
        User user = (User) method.invoke(service,args);
    
        dos.writeInt(user.getId());
        dos.writeUTF(user.getName());
        dos.flush();
    }
}

标签:java,bill,50,230104,RPC,oos,new,import,com
From: https://www.cnblogs.com/wcwblog/p/17026355.html

相关文章