【诗119:130】你的言语一解开,就发出亮光,使愚人通达。
目录
-
创建两个项目
服务端:rpc-server-all
客户端:rpc-client
-
rpc-server-all(服务端实现)
服务端创建两个模块
- rpc-server-api:供客户端使用的 API
- rpc-server-provider: api 的具体实现以及 bio 服务器的实现
-
rpc-server-api
IHelloSevice(对外发布的接口)
public interface IHelloSevice {
String sayHello(String name);
void saveUser(User user);
}
RpcRequest(请求体),自己生成 get和set
package com.ddup.rpc;
import java.io.Serializable;
/**
* 请求体
*/
public class RpcRequest implements Serializable {
public String className;//类名
public String methodName;//方法名
public Object[] parameters;//请求实参
}
User (业务entity,get和set忽略,自己生成)
public class User implements Serializable {
private String name;
private int age;
}
最后:maven -> install(把此模块打成 jar 到本地仓库,对外提供调用)
-
rpc-server-provider
pom.xml 引入 rpc-server-api
<dependency>
<groupId>com.ddup.rpc</groupId>
<artifactId>rpc-server-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
业务实现
public class HelloServerImpl implements IHelloSevice {
@Override
public String sayHello(String name) {
System.out.println("reqeust in content : " + name);
return "hello " + name;
}
@Override
public void saveUser(User user) {
System.out.println("request in saveUser : "+ user.toString());
}
服务端:RpcProxyServer
package com.ddup.rpc;
/**
* 服务端:阻塞接收请求
*/
public class RpcProxyServer {
/**
* 缓存线程池
*/
private ExecutorService executorService = Executors.newCachedThreadPool();
public void publish(int port, Object service) {
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(port);
while (true) {
Socket socket = serverSocket.accept();
// 利用多线程处理任务
executorService.execute(new ProcessorHandler(socket, service));
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (serverSocket != null) {
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
请求处理类:ProcessorHandler
package com.ddup.rpc;
/**
* 用以处理请求,反射实现
*/
public class ProcessorHandler implements Runnable {
private Socket socket;
private Object service;
public ProcessorHandler(Socket socket, Object service) {
this.socket = socket;
this.service = service;
}
@Override
public void run() {
try {
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
RpcRequest request = (RpcRequest) ois.readObject();
Object result = invoke(request);
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
// 结果返回给客户端
oos.writeObject(result);
oos.flush();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public Object invoke(RpcRequest request) {
Object result = null;
try {
// 获取形参类型
Object[] parameters = request.getParameters();
Class<?>[] parameterTypes = new Class[parameters.length];
for (int i = 0; i < parameters.length; i++) {
parameterTypes[i] = parameters[i].getClass();
}
String className = request.getClassName();
Class<?> clzz = Class.forName(className);
String methodName = request.getMethodName();
// 找到方法
Method method = clzz.getMethod(methodName, parameterTypes);
//反射调用
result = method.invoke(service, parameters);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return result;
}
}
启动
package com.ddup.rpc;
/**
* Hello world!
*/
public class App {
public static void main(String[] args) {
HelloServerImpl helloServer = new HelloServerImpl();
RpcProxyServer rpcProxyServer = new RpcProxyServer();
rpcProxyServer.publish(8080,helloServer);
}
}
服务端结构
服务端完成.......
-
rpc-client(客户端实现)
RpcProxyClient)
package com.ddup.rpc;
import java.lang.reflect.Proxy;
/**
* 客户端:用以生成所要调用接口的代理类
*/
public class RpcProxyClient {
public <T> T clientProxy(final Class<T> interfaceCls,String host,int port) {
return (T)Proxy.newProxyInstance(interfaceCls.getClassLoader(), new Class<?>[]{interfaceCls}, new RemoteInvocationHandler(host,port));
}
}
RemoteInvocationHandler
实现 InvocationHandler 接口,用以生成代理类,持有代理方法 #invoke
package com.ddup.rpc; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; /** * 执行真正方法的类,实现 InvocationHandler 接口 */ public class RemoteInvocationHandler implements InvocationHandler { private String host; private int port; public RemoteInvocationHandler(String host, int port) { this.host = host; this.port = port; } /** * 代理方法 */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("client come in invoking..."); // 请求体 RpcRequest request = new RpcRequest(); request.setClassName(method.getDeclaringClass().getName()); request.setMethodName(method.getName()); request.setParameters(args); // 发起网络传输 RpcNetTransport rpcNetTransport = new RpcNetTransport(host, port); Object result = rpcNetTransport.send(request); return result; } }
RpcNetTransport
用以发起真正的网络传输,处理请求和响应
package com.ddup.rpc; import java.io.*; import java.net.Socket; /** * 发起网络传输的类 */ public class RpcNetTransport { private String host; private int port; public RpcNetTransport(String host, int port) { this.host = host; this.port = port; } public Object send(RpcRequest request) { Object result = null; ObjectOutputStream oos = null; ObjectInputStream ois = null; try { Socket socket = null; try { socket = new Socket(host, port); } catch (IOException e) { e.printStackTrace(); } OutputStream os = socket.getOutputStream(); oos = new ObjectOutputStream(os); oos.writeObject(request); oos.flush(); InputStream is = socket.getInputStream(); ois = new ObjectInputStream(is); result = ois.readObject(); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } finally { if (ois != null) { try { ois.close(); } catch (IOException e) { e.printStackTrace(); } } if (oos != null) { try { oos.close(); } catch (IOException e) { e.printStackTrace(); } } } return result; } }
启动
package com.ddup.rpc;
/**
* Hello world!
*/
public class App {
public static void main(String[] args) {
RpcProxyClient rpcProxyClient = new RpcProxyClient();
IHelloSevice iHelloSevice = rpcProxyClient.clientProxy(IHelloSevice.class,"localhost",8080);
String zqr = iHelloSevice.sayHello("zqr");
System.out.println(zqr);
}
}
客户端结构
-
完成 -> 测试
#main启动服务端 -> #main 启动客户端 —> 成功
服务端打印
客户端打印
-
源码
服务端 git@github.com:qingruizhu/rpc-server-all.git
客户端 git@github.com:qingruizhu/rpc-client.git
左手圣经,右手Java
灵魂指导思想,思想更新技术
一个对圣经感兴趣的Java菜鸟 ? -> 留言指导哦?亲