1.目录整体结构如下
1.服务端定义接口为HelloService
package cn.rpc.demo.service;
/**
* @author insulators
* @date 2019/5/27 14:29
**/
public interface HelloService {
public void sayHello(String info);
}
2.在服务端实现helloService
package cn.rpc.demo.service.impl;
import cn.rpc.demo.service.HelloService;
/**
* @author insulators
* @date 2019/5/27 14:29
**/
public class HelloServiceImpl implements HelloService {
@Override
public void sayHello(String info) {
System.out.println("Hello"+info);
}
}
3.在服务端rpc服务端
package org.rpc.server;
import com.google.common.collect.Maps;
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;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* @author insulators
* @date 2019/5/27 14:29
**/
public class RpcServer {
private ConcurrentMap<Object, Object> severList = Maps.newConcurrentMap();
private ThreadPoolExecutor pol = new ThreadPoolExecutor(8, 30, 1000, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(10));
public void start(int port) throws IOException {
ServerSocket serverSocket = new ServerSocket(port);
Socket socket = serverSocket.accept();
System.out.println("==================服务启动成功==================");
//执行线程任务
pol.execute(new ServerTask(socket));
}
//发布接口服务
public void publisherServer(Class<?> clz, Class<?> clzImpl) throws IllegalAccessException, InstantiationException {
System.out.println("==================接口发布成功==================");
severList.put(clz.getName(), clzImpl.newInstance());
}
//线程任务
private class ServerTask implements Runnable {
private final Socket socket;
private ServerTask(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try (ObjectInputStream input = new ObjectInputStream(socket.getInputStream());
ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream());) {
String serviceName = input.readUTF();
String methodName = input.readUTF();
Class<?>[] paramType = (Class<?>[]) input.readObject();
Object[] params = (Object[]) input.readObject();
Object instance = severList.get(serviceName);
if (instance == null) {
System.out.println("服务不存在");
}
Method method = instance.getClass().getDeclaredMethod(methodName, paramType);
if (method == null) {
System.out.println("方法不存在");
return;
}
output.writeObject(method.invoke(instance, params));
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
4.在客户端引入HelloService接口
5.在客户端实现调用
package org.rpc.client;
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;
/**
* @author insulators
* @date 2019/5/27 14:29
**/
public class RpcClient {
public <T> T proxyClient(final Class<?> clazz, final int port) {
return (T) Proxy.newProxyInstance(clazz.getClassLoader(), new Class<?>[]{clazz}, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Socket socket = new Socket("localhost", port);
try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream());
) {
objectOutputStream.writeUTF(clazz.getName());
objectOutputStream.writeUTF(method.getName());
objectOutputStream.writeObject(method.getParameterTypes());
objectOutputStream.writeObject(args);
return objectInputStream.readObject();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
});
}
}
6.启动服务端发布服务
package cn.rpc.demo;
import cn.rpc.demo.service.HelloService;
import cn.rpc.demo.service.impl.HelloServiceImpl;
import org.rpc.server.RpcServer;
import java.io.IOException;
/**
* @author insulators
* @date 2019/5/27 14:29
**/
public class App
{
public static void main( String[] args ) throws IOException, InstantiationException, IllegalAccessException {
RpcServer rpcServer = new RpcServer();
rpcServer.publisherServer(HelloService.class, HelloServiceImpl.class);
rpcServer.start(8000);
}
}
7.启动客户端调用服务
public class App
{
public static void main( String[] args ) {
RpcClient rpcClient = new RpcClient();
HelloService helloService = rpcClient.proxyClient(HelloService.class, 8000);
helloService.sayHello("测试rpc服务调用");
}
}
8.结果