您的位置:首页 > 其它

自定义RPC框架的简单实现

2018-07-22 18:51 363 查看
[code]package com.remote.service;

/**
* Created by 79782 on 2018/7/22.
*/
public interface HelloService {
public String sayHello(String name);
}
[code]package com.remote.service;

/**
* Created by 79782 on 2018/7/22.
*/
public class HelloServiceImpl implements HelloService {
public String sayHello(String name) {
return "hello:"+name;
}
}
[code]package com.remote.server;

/**
* Created by 79782 on 2018/7/22.
*/
public interface Server {
public void start();
public void stop();
public void register(Class server ,Class serviceImpl);
}
[code]package com.remote.server;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Method;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
* Created by 79782 on 2018/7/22.
*/
public class ServerCenter implements Server {
private static HashMap<String,Class> serviceRegiser=new HashMap();
private static int port;
private static ExecutorService executor= Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
private static boolean isRunning=false;
public static void setPort(int port) {
ServerCenter.port = port;
}

public void start() {
isRunning=true;
ServerSocket server=null;
try {
server=new ServerSocket();
server.bind(new InetSocketAddress(9999));
} catch (IOException e) {
e.printStackTrace();
}
while(true){

try {
//等待客户端连接 接受客户端连接及请求
Socket socket = server.accept();
executor.execute(new ServiceTask(socket));

} catch (Exception e) {
e.printStackTrace();
}
}

}

public void stop() {
isRunning=false;
executor.shutdown();
}

public void register(Class server ,Class serviceImpl) {
serviceRegiser.put(server.getName(),serviceImpl);
}

private static class ServiceTask implements Runnable{
private Socket socket;

public ServiceTask() {
}

public ServiceTask(Socket socket) {
this.socket = socket;
}

public void run() {
ObjectInputStream ois=null;
ObjectOutputStream oos =null;
try {
//Object流有顺序
ois= new ObjectInputStream(socket.getInputStream());
//因为ObjectInputeStream对发送数据的数据严格要求,所以可以一个一个接受
String serviceName=ois.readUTF();
String methodName=ois.readUTF();
Class[] paramType= (Class[]) ois.readObject();
Object[] arguments= (Object[]) ois.readObject();
//根据请求找到请求的接口
Class serviceClass = serviceRegiser.get(serviceName);
Method method = serviceClass.getMethod(methodName, paramType);
Object result=method.invoke(serviceClass.newInstance(), arguments);
oos= new ObjectOutputStream(socket.getOutputStream());
oos.writeObject(result);
}catch (Exception e) {
e.printStackTrace();
}finally {
if(oos!=null){
try {
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(ois!=null){
try {
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
}
[code]package com.remote.client;

import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.net.InetSocketAddress;
import java.net.Socket;

/**
* Created by 79782 on 2018/7/22.
*/
public class Client {
//获取代表服务端接口的动态代理对象
//serviceName:客户端向服务端请求的接口名
@SuppressWarnings("unchecked")
public static <T> T getRemoteProxyObj(final Class serviceInterface, final InetSocketAddress addr){
return (T)Proxy.newProxyInstance(serviceInterface.getClassLoader(), new Class<?>[]{serviceInterface}, new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
ObjectOutputStream oos=null;
ObjectInputStream ois=null;
try{
Socket socket=new Socket();
socket.connect(addr);
oos= new ObjectOutputStream(socket.getOutputStream());
//接口名、接口方法名、方法类型,方法参数、
oos.writeUTF(serviceInterface.getName());
oos.writeUTF(method.getName());
oos.writeObject(method.getParameterTypes());
oos.writeObject(args);
//等待服务端处理
//服务端处理返回结果
ois= new ObjectInputStream(socket.getInputStream());
return ois.readObject();
}catch (Exception e){
e.printStackTrace();
return null;
}finally {
if(ois!=null){
ois.close();
}
if(oos!=null){
oos.close();
}
}
}
});

}
}
[code]package com.remote.server;

import com.remote.service.HelloService;
import com.remote.service.HelloServiceImpl;

/**
* Created by 79782 on 2018/7/22.
*/
public class ServerMain {
/**
服务端将可以提供的接口注册到服务中心 通过map保存key:发布接口的名字,value:接口的实现类
服务端接收客户端请求后,通过请求的接口名在服务中心的map中寻找对应的接口实现类。
解析客户端发送的方法名,接口名,解析完毕后通过反射技术将该方法执行
执行完毕后将结果返回给客户端

*/
public static void main(String[] args) {
new Thread(new Runnable() {
public void run() {
Server server=new ServerCenter();
server.register(HelloService.class, HelloServiceImpl.class);
server.start();
}
}).start();
}
}
[code]package com.remote.client;

import com.remote.service.HelloService;

import java.net.InetSocketAddress;

/**
* Created by 79782 on 2018/7/22.
*/
public class ClientMain {
public static void main(String[] args) throws ClassNotFoundException {
/**
* 客户端通过socket请求服务端,并且通过字符串形式将请求的接口名发送给服务端
* 动态代理:发送接口名,方法参数
*/

HelloService helloService=Client.getRemoteProxyObj(
Class.forName("com.remote.service.HelloService"),
new InetSocketAddress("127.0.0.1",9999));
System.out.println(helloService.sayHello("yanfang"));
}
}

 

阅读更多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: