实现rpc就是这么简单~

实现rpc就是这么简单~

日后补充完善(缺少负载均衡,服务注册发现等,不过加入这些很容易,明白了rpc其中原理就简单了~)

 

1.服务端:

1)服务端其实就是将客户端传输的指定方法和参数,通过反射调用后,将值传回给客户端;

伪代码:

@Component
public class AmaniServer implements ApplicationContextAware, InitializingBean {
    @Override
    public void afterPropertiesSet() throws Exception {
        new Thread(() -> {
            EventLoopGroup bossGroup = new NioEventLoopGroup();
            EventLoopGroup workerGroup = new NioEventLoopGroup();
            try {
            ...    
                  //处理类
                  pipeline.addLast(new AmaniServerHandler(beans));
            ...
                future.channel().closeFuture().sync();
            } catch (InterruptedException e) {
                throw new RuntimeException("Server shutdown!", e);
            } finally {
                workerGroup.shutdownGracefully();
                bossGroup.shutdownGracefully();
            }
        }).start();
    }
}

处理类:
 @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, AmaniRequest request) throws Exception {
        AmaniResponse amaniResponse = new AmaniResponse();
        amaniResponse.setRequestId(request.getRequestId());
        try {
            amaniResponse.setResult(handleRequest(request));
        } catch (Exception e) {
            amaniResponse.setT(e);
            log.error("hanlding request:{}", e);
        }

    private Object handleRequest(AmaniRequest request) throws Exception {
        Object o = beans.get(request.getInterfaceName());
        ...
        Method method = o.getClass().getMethod(request.getMethodName(), request.getParameterTypes());
        method.setAccessible(true);
        //返回反射调用方法的结果
        return method.invoke(o, request.getParameters());
    }

 

2)后续增加服务注册发现也是在这里,将本地ip及端口添加的zookeeper等~

 

 

2.客户端:

1)客户端就是将本地需要远程调用的接口增加动态代理,动态代理方法的结果就是通过调用远程服务器获取的,将代理对象装配到spring中;

伪代码:

public class AmaniProxy implements FactoryBean<Object> {


    private Object doInvoke(Object proxy, Method method, Object[] args) throws Throwable {
        String targetServiceName = type.getName();
        AmaniRequest request = new AmaniRequest();
        request.setRequestId(generateRequestId(targetServiceName));
        request.setInterfaceName(method.getDeclaringClass().getName());
        request.setMethodName(method.getName());
        request.setParameters(args);
        request.setParameterTypes(method.getParameterTypes());

        InetSocketAddress serviceAddress = new InetSocketAddress("127.0.0.1", 8888);

        Channel channel = ChannelManager.getInstance().getChannel(serviceAddress);
        if (null == channel) {
            throw new RuntimeException("Cann't get channel for address" + serviceAddress);
        }
        //调用远程方法获取结果
        AmaniResponse response = sendRequest(channel, request);
        ...
        return response.getResult();
        }
    }

//装配到spring,等待调用
@Component
public class AmaniClient implements BeanDefinitionRegistryPostProcessor {

    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        ClassPathScanningCandidateComponentProvider scanner = getScanner();
        scanner.addIncludeFilter(new AnnotationTypeFilter(AmaniReference.class));
        String basePackage = getPackage(registry);
        Set<BeanDefinition> candidateComponents = scanner
                .findCandidateComponents(basePackage.equals("") ? getBasePackage(registry) : basePackage);
        for (BeanDefinition candidateComponent : candidateComponents) {
            if (candidateComponent instanceof AnnotatedBeanDefinition) {
                AnnotatedBeanDefinition beanDefinition = (AnnotatedBeanDefinition) candidateComponent;
                AnnotationMetadata annotationMetadata = beanDefinition.getMetadata();
                BeanDefinitionHolder holder = createBeanDefinition(annotationMetadata);
                BeanDefinitionReaderUtils.registerBeanDefinition(holder, registry);
            }
        }
    }

 

 

 

源码奉上~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值