手写RPC框架

服务接口

public interface EchoService {
    String echo(String ping);
}

服务端实现

public class EchoServiceImpl implements EchoService {
    @Override
    public String echo(String ping) {
        return ping != null ? ping + " ---> Hello, thank you." : "Thank you very much.";
    }
}

暴露服务

public class RpcExporter {
   static Logger logger = Logger.global;
   static Executor executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());

   public static void exporter(String hostName, Integer port) throws IOException {
       ServerSocket server = new ServerSocket();
       server.bind(new InetSocketAddress(hostName, port));
       try {

           while (true) {
               executor.execute(new ExporterTask(server.accept()));
           }
       } catch (Throwable throwable) {
           throwable.printStackTrace();
       } finally {
           try {
               server.close();
           } catch (Exception e) {
               e.printStackTrace();
           }
       }
   }

   private static class ExporterTask implements Runnable {
       Socket client = null;

       public ExporterTask(Socket client) {
           this.client = client;
       }

       private Class getImplClazz(Class clazz) {
           Reflections reflections = new Reflections("com.maxiaoba.sample");
           Set<Class> subTypesOf = reflections.getSubTypesOf(clazz);
           return subTypesOf.iterator().next();
       }

       @Override
       public void run() {
           ObjectInputStream input = null;
           ObjectOutputStream output = null;
           try {
               input = new ObjectInputStream(client.getInputStream());
               String interfaceName = input.readUTF();
               Class<?> service = getImplClazz(Class.forName(interfaceName));
               String methodName = input.readUTF();
               Class<?>[] parameterTypes = (Class<?>[]) input.readObject();
               Object[] arguments = (Object[]) input.readObject();
               Method method = service.getMethod(methodName, parameterTypes);
               Object result = method.invoke(service.newInstance(), arguments);
               output = new ObjectOutputStream(client.getOutputStream());
               output.writeObject(result);
           } catch (IOException e) {
               e.printStackTrace();
           } catch (Exception e) {
               e.printStackTrace();
           } finally {
               try {
                   if (input != null) {
                       input.close();
                   }
               } catch (IOException e) {
                   e.printStackTrace();
               }
               try {
                   if (output != null) {
                       output.close();
                   }
               } catch (IOException e) {
                   e.printStackTrace();
               }
           }
       }
   }
}

客户端

public class RpcImporter<S> {
    public S importer(Class<?> serverClass, InetSocketAddress socketAddress) {
        return (S) Proxy.newProxyInstance(serverClass.getClassLoader(), new Class<?>[]{ serverClass }, (proxy, method, args) -> {
            Socket socket = null;
            ObjectInputStream inputStream = null;
            ObjectOutputStream outputStream = null;
            try {
                socket = new Socket();
                socket.connect(socketAddress);

                outputStream = new ObjectOutputStream(socket.getOutputStream());
                outputStream.writeUTF(serverClass.getName());
                outputStream.writeUTF(method.getName());
                outputStream.writeObject(method.getParameterTypes());
                outputStream.writeObject(args);

                inputStream = new ObjectInputStream(socket.getInputStream());
                return inputStream.readObject();
            } finally {
                if (inputStream != null) {
                    inputStream.close();
                }
                if (outputStream != null) {
                    outputStream.close();
                }
            }
        });
    }
}

启动服务端,调用服务端接口

public class Main {
    public static void main(String[] args) {
        
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    RpcExporter.exporter("localhost", 8088);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
        // 启动服务端
        thread.start();
        RpcImporter<EchoService> importer = new RpcImporter<>();
        // 客户端只需要以来接口即可
        EchoService echoService = importer.importer(EchoService.class, new InetSocketAddress("localhost", 8088));
        String echo = echoService.echo("Are you ok");
        thread.stop();
        System.out.println(echo);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值