RPC(Romote Procedure Call):远程过程调用,允许一台计算机程序远程调用另外一台计算机的子程序,不用关心底层,网络通信,在socket基础上实现,比socket需要更多资源。
先看demo实现 如下 分为client端和server端
Client实现如下:
接口
package com.gupao.rmi.Demo.rpcClient;
public interface HelloService {
StringsayHello(String msg);
}
package com.gupao.rmi.Demo.rpcClient;
import java.lang.reflect.Proxy;
import java.net.InetSocketAddress;
/**
*客户端代理
*/
public class Client {
public T clientProy(Class className, InetSocketAddress address) {
return (T) Proxy.newProxyInstance(className.getClassLoader(), new Class[] {className},
new RemoteHandler(address, className));
}
}
建立socket发送数据
package com.gupao.rmi.Demo.rpcClient;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.net.InetSocketAddress;
import java.net.Socket;
public class RemoteHandlerimplements InvocationHandler {
private InetSocketAddressaddress;
private ClassaClass;
public RemoteHandler(InetSocketAddress address, Class aClass) {
this.address = address;
this.aClass = aClass;
}
@Override
public Objectinvoke(Object proxy, Method method, Object[] args)throws Throwable {
Socket socket =null;
Object result =null;
ObjectInputStream objectInputStream =null;
ObjectOutputStream objectOutputStream =null;
try {
socket =new Socket();
socket.connect(address);
objectOutputStream =new ObjectOutputStream(socket.getOutputStream());
//发送接口名
objectOutputStream.writeUTF(aClass.getName());
//发送方法名
objectOutputStream.writeUTF(method.getName());
//参数类型
objectOutputStream.writeObject(method.getParameterTypes());
//参数名称
objectOutputStream.writeObject(args);
objectOutputStream.flush();
objectInputStream =new ObjectInputStream(socket.getInputStream());
result = objectInputStream.readObject();
objectOutputStream.close();
objectInputStream.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (objectInputStream !=null) objectInputStream.close();
if (objectOutputStream !=null) objectOutputStream.close();
if (!socket.isClosed()) socket.close();
}
return result;
}
}
测试类
package com.gupao.rmi.Demo.rpcClient;
import java.net.InetSocketAddress;
public class TestRpcClient {
public static void main(String[] args) {
HelloService helloService =new Client().clientProy(HelloService.class, new InetSocketAddress("127.0.0.1", 8080));
System.out.print(helloService.sayHello("wxw"));
}
}
Server 端 接口
package com.gupao.rmi.Demo.rpcServer;
public interface HelloService {
StringsayHello(String msg);
}
实现类
package com.gupao.rmi.Demo.rpcServer;
public class HelloServiceImplimplements HelloService {
@Override
public StringsayHello(String msg) {
return "hello" + msg;
}
}
建立服务端
package com.gupao.rmi.Demo.rpcServer;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ServiceServer {
//启用线程池
private static final ExecutorServiceexecutorService = Executors.newCachedThreadPool();
private int port =0;
public ServiceServer(int port) {
this.port = port;
}
public void start() {
ServerSocket serverSocket =null;
Socket socket =null;
try {
try {
System.out.print("打开服务ServerSocket");
serverSocket =new ServerSocket();
serverSocket.bind(new InetSocketAddress(port));
socket = serverSocket.accept();
//等待客户端连接启动线程用于多个任务调用服务端
while (true) {
System.out.print("客户端开始连接服务...");
executorService.execute(new ServiceTask(socket));
}
} catch (IOException e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
服务端接受数据并处理
package com.gupao.rmi.Demo.rpcServer;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.Socket;
public class ServiceTaskimplements Runnable {
private Socketsocket;
public ServiceTask(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
//做服务传输通信用字节流的方式实现
ObjectOutputStream objectOutputStream =null;
ObjectInputStream objectInputStream =null;
try {
System.out.print("客户端已经连接...");
objectInputStream =new ObjectInputStream(socket.getInputStream());
//获取客户端发送过来的接口
String name = objectInputStream.readUTF();
/ /获取客户端发送过来的方法名称
String methodName = objectInputStream.readUTF();
//获取客户端参数类型
Class[] methodTypes = (Class[])objectInputStream.readObject();
//获取客户端的参数值
Object[] args = (Object[]) objectInputStream.readObject();
//获取从客户传来的方法
Class className = name.getClass();
Method method = className.getMethod(methodName, methodTypes);
Object result = method.invoke(className.newInstance(), args);
objectOutputStream =new ObjectOutputStream(socket.getOutputStream());
objectOutputStream.writeObject(result);
objectInputStream.close();
objectOutputStream.close();
} catch (IOException | ClassNotFoundException | NoSuchMethodException |
InstantiationException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
} finally {
try {
if (objectInputStream !=null) objectInputStream.close();
if (objectOutputStream !=null ) objectOutputStream.close();
if (!socket.isClosed())socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
启动服务端
public class TestRpcServer {
public static void main(String[] args) {
ServiceServer serviceServer =new ServiceServer(8080);
serviceServer.start();
}
}