手写RPC 通信,在客户端转入类,方法给服务端,服务端执行后,将执行结果通过socket发回给客户端:
坑记录: 客户端因为只知道调用 方法的接口,不知道接口方法的实现,所以在客户端生成代理对象的时候,传入是参数应该接口的class type, 那在代码函数中,生成代理对象的newProxyInstance时, 第二个参数就不能为clazz.getInterface, 而应该用new class[]{clazz}. 因为传入的参数已经是interface type, 就不用再getInterface()了。
以下是客户端代码:
package com.rpc.yubo;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.net.Socket;
public class ClientProxyObject<T> {
public T genProxy(Class<T> clazz)
{
return (T) (
Proxy.newProxyInstance(
clazz.getClassLoader(),
new Class[] {clazz}, // 注意这里不是用clazz.getInterfaces(), 因为clazz 本来就是interface了
//clazz.getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable{
// write method to server
Socket s = new Socket("127.0.0.1", 8123);
Object obj = null;
ObjectOutputStream oos = new ObjectOutputStream(s.getOutputStream());
try
{
oos.writeUTF(method.getName());
oos.writeObject(args);
oos.flush();
}
catch(Exception ex)
{
ex.printStackTrace();
}
// get result and return
ObjectInputStream ois = new ObjectInputStream(s.getInputStream());
try
{
obj = ois.readObject();
}
catch(Exception ex)
{
ex.printStackTrace();
}
finally
{
s.close();
}
return obj;
}
}
)
);
}
public static void main(String[] args) throws InterruptedException {
ClientProxyObject<IHello> helloProxy = new ClientProxyObject<>();
IHello hello = helloProxy.genProxy(IHello.class); // 注意这里传的接口,不是实现类,因为客户端不会知道实现类
String s = hello.sayHello("hi 1 from client");
System.out.println( "xx" + s);
while(true) {
System.out.println( "xxx" + s);
Thread.sleep(100000000);
}
}
}
客户端和服务端均有以下代码:
package com.rpc.yubo;
public interface IHello {
public String sayHello(String args);
}
服务端代码:
public class IHelloImpl implements IHello {
@Override
public String sayHello(String args) {
// TODO Auto-generated method stub
System.out.println("Server say" + args);
return args + "--hehe";
}
}
服务端代码:
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Method;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerPulisher {
// create serverSocket to accept
// read method
// run method
// write result object
public void pulicServer() throws IOException
{
IHello hello = new IHelloImpl();
ServerSocket socket = new ServerSocket(8123);
while(true)
{
System.out.println("Server start:");
Socket client = socket.accept();
try(ObjectInputStream ois = new ObjectInputStream( client.getInputStream() )){
String method = ois.readUTF();
Object [] objects = (Object [])ois.readObject();
Class<?>[] types = new Class[objects.length];
for(int i = 0; i < objects.length; i++)
{
types[i] = objects[i].getClass();
}
System.out.println("Server received:" + method);
Method m = IHelloImpl.class.getMethod(method, types);
Object result = m.invoke(hello, objects);
ObjectOutputStream oos = new ObjectOutputStream(client.getOutputStream());
try
{
System.out.println("Server write:" + result.toString());
oos.writeObject(result);
// oos.writeObject("xxx");
//oos.flush();
}
catch(Exception ex) {
ex.printStackTrace();
}
}
catch(Exception ex) {
ex.printStackTrace();
}
}
}
}
服务端代码:
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Method;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerService {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
// create server object
// run accept
new ServerPulisher().pulicServer();
}
}