• 自行实现一个简易RPC框架


    10分钟写一个RPC框架

    1、RpcFramework

    package com.alibaba.study.rpc.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; 
    
    /**
     * 自行实现一个简易RPC框架
     * @author wangwei03
     */
    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();  
                                        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 
         */  
        @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();  
                    }  
                }  
            });  
        }  
      
    }  

    2、Provider

    package com.alibaba.study.rpc.test;
    
    /** 
     * HelloService 
     * 定义服务接口
     * @author william.liangf 
     */  
    public interface HelloService {
        String hello(String name);  
    }
    package com.alibaba.study.rpc.test;  
      
    /** 
     * HelloServiceImpl 
     * 实现服务
     * @author william.liangf 
     */  
    public class HelloServiceImpl implements HelloService {  
      
        public String hello(String name) {  
            return "Hello " + name;  
        }  
      
    }  
    package com.alibaba.study.rpc.test;  
      
    import com.alibaba.study.rpc.framework.RpcFramework;  
      
    /** 
     * RpcProvider 
     * 暴露服务
     * @author william.liangf 
     */  
    public class RpcProvider {  
      
        public static void main(String[] args) throws Exception {  
            HelloService service = new HelloServiceImpl();  
            RpcFramework.export(service, 1234);  
        }  
      
    }  

    3、Consumer

    package com.alibaba.study.rpc.test;  
      
    import com.alibaba.study.rpc.framework.RpcFramework;  
      
    /** 
     * RpcConsumer 
     * 引用服务
     * @author william.liangf 
     */  
    public class RpcConsumer {  
          
        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://javatar.iteye.com/blog/1123915

  • 相关阅读:
    什么企业邮箱安全性高?国内哪家企业邮箱好用?
    163VIP邮箱外贸群发技巧有哪些?
    163邮箱如何群发邮件?外贸邮箱群发哪个效果好?
    登录163邮箱续费情况怎么查询?163vip邮箱怎么收费?
    Java面试题总结之Java基础(二)
    Java面试题总结之Java基础(一)
    Exception in thread "baseScheduler_QuartzSchedulerThread" java.lang.OutOfMemoryError: GC
    Maven项目报错:java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderListener
    如何下载Github上项目源码打包到本地Maven仓库
    HTML日期时间插件
  • 原文地址:https://www.cnblogs.com/wangweiNB/p/5286927.html
Copyright © 2020-2023  润新知