- 上述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();
}
}