实现java RPC框架

主要利用socket通信,反射,代理实现类似RMI的RPC框架

首先是框架的代码

package framework;  

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.ServerSocket;  
import java.net.Socket;  

/**  
 * RpcFramework  
 *   
 * @author william.liangf  
 */  
public class RpcFramework {  

    /**  
     * 暴露服务  
     *   
     * @param service 服务实现  
     * @param port 服务端口  
     * @throws Exception  
     */  
    public static void export(final Object service, int port) throws Exception {  
        if (service == null)  
            throw new IllegalArgumentException("service instance == null");  
        if (port <= 0 || port > 65535)  
            throw new IllegalArgumentException("Invalid port " + port);  
        System.out.println("Export service " + service.getClass().getName() + " on port " + port);  
        ServerSocket server = new ServerSocket(port);  
        for(;;) {  
            try {  
                final Socket socket = server.accept();//服务器端一旦收到消息,就创建一个线程进行处理  
                new Thread(new Runnable() {  
                    @Override  
                    public void run() {  
                        try {  
                            try {  
                                ObjectInputStream input = new ObjectInputStream(socket.getInputStream());  
                                try {  
                                    String methodName = input.readUTF();//service是服务器端提供服务的对象,但是,要通过获取到的调用方法的名称,参数类型,以及参数来选择对象的方法,并调用。获得方法的名称  
                                    Class<?>[] parameterTypes = (Class<?>[])input.readObject();//获得参数的类型  
                                    Object[] arguments = (Object[])input.readObject();//获得参数  
                                    ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream());  
                                    try {  
                                        Method method = service.getClass().getMethod(methodName, parameterTypes);//通过反射机制获得方法  
                                        Object result = method.invoke(service, arguments);//通过反射机制获得类的方法,并调用这个方法  
                                        output.writeObject(result);//将结果发送  
                                    } catch (Throwable t) {  
                                        output.writeObject(t);  
                                    } finally {  
                                        output.close();  
                                    }  
                                } finally {  
                                    input.close();  
                                }  
                            } finally {  
                                socket.close();  
                            }  
                        } catch (Exception e) {  
                            e.printStackTrace();  
                        }  
                    }  
                }).start();  
            } catch (Exception e) {  
                e.printStackTrace();  
            }  
        }  
    }  

    /**  
     * 引用服务  
     *   
     * @param <T> 接口泛型  
     * @param interfaceClass 接口类型  
     * @param host 服务器主机名  
     * @param port 服务器端口  
     * @return 远程服务  
     * @throws Exception  
     *///原理是通过代理,获得服务器端接口的一个“代理”的对象。对这个对象的所有操作都会调用invoke函数,在invoke函数中,是将被调用的函数名,参数列表和参数发送到服务器,并接收服务器处理的结果  
    @SuppressWarnings("unchecked")  
    public static <T> T refer(final Class<T> interfaceClass, final String host, final int port) throws Exception {  
        if (interfaceClass == null)  
            throw new IllegalArgumentException("Interface class == null");  
        if (! interfaceClass.isInterface())  
            throw new IllegalArgumentException("The " + interfaceClass.getName() + " must be interface class!");  
        if (host == null || host.length() == 0)  
            throw new IllegalArgumentException("Host == null!");  
        if (port <= 0 || port > 65535)  
            throw new IllegalArgumentException("Invalid port " + port);  
        System.out.println("Get remote service " + interfaceClass.getName() + " from server " + host + ":" + port);  
        return (T) Proxy.newProxyInstance(interfaceClass.getClassLoader(), new Class<?>[] {interfaceClass}, new InvocationHandler() {  
            public Object invoke(Object proxy, Method method, Object[] arguments) throws Throwable {  
                Socket socket = new Socket(host, port);  
                try {  
                    ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream());  
                    try {  
                        output.writeUTF(method.getName());  
                        output.writeObject(method.getParameterTypes());  
                        output.writeObject(arguments);  
                        ObjectInputStream input = new ObjectInputStream(socket.getInputStream());  
                        try {  
                            Object result = input.readObject();  
                            if (result instanceof Throwable) {  
                                throw (Throwable) result;  
                            }  
                            return result;  
                        } finally {  
                            input.close();  
                        }  
                    } finally {  
                        output.close();  
                    }  
                } finally {  
                    socket.close();  
                }  
            }  
        });  
    }  

}  

服务接口

package user;    

public interface  HelloService {    
    String hello(String name);    
}    

实现服务
[java] view plain copy

package user;    

public class HelloServiceImpl implements HelloService{    
    public String hello(String name) {    
        return "Hello " + name;    
    }    

}    

服务器

package user;  
import framework.RpcFramework;  

public class Server {  
    public static void main(String []args) throws Exception {  
        HelloService service = new HelloServiceImpl();  
        RpcFramework.export(service, 1234);   
    }  
}  

客户机

package user;  
import framework.RpcFramework;  

public class Client {  
    public static void main(String[] args) throws Exception {    
        HelloService service = RpcFramework.refer(HelloService.class, "127.0.0.1", 1234);    
        for (int i = 0; i < Integer.MAX_VALUE; i ++) {    
            String hello = service.hello("World" + i);    
            System.out.println(hello);    
            Thread.sleep(1000);    
        }    
    }    
}  

转载自http://blog.csdn.net/liusuper2088/article/details/41117889

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值