zoukankan      html  css  js  c++  java
  • dubbo的url里面带的callback是怎么用的?

    在url里面指定某个参数方法的第几个参数是一个callback,也就是说这个实参是一个callback,虽然消费者把这个callback实例传给了提供者,但是提供者实际本地没有这个callback实例,提供者只能继续远程调用消费者这个callback拿到结果。

    比如消费者和提供者都在url里面指定 xxx.0.callback=true,表示xxx这个method的第0个参数是一个callback。

    提供者有这样一个接口服务:

    public void xxx(IDemoCallback callback, String arg1, int runs, int sleep);

    提供者具体实现:

    public void xxx(final IDemoCallback callback, String arg1, final int runs, final int sleep) {
    callback.yyy("Sync callback msg .This is callback data. arg1:" + arg1);
    System.out.println("xxx invoke complete");
    }

    对于提供者来说,这个callback是消费传过来的一个实例,本地没有,那么在调用的时候如果执行到callback只能远程调用消费者这个callback实例拿到结果再继续运行

    System.out.println("xxx invoke complete");

    消费者调用了方式:

    demoProxy.xxx(new IDemoCallback() {
    public String yyy(String msg) {
    System.out.println("Recived callback: " + msg);
    count.incrementAndGet();
    return "ok";
    }
    }, "other custom args", 10, 100);


    下面解释下dubbo如何做的。对于一个rpc调用是这么序列化的:

    method-name按照striing序列化

    parameter-type按照类型的描述符的string进行序列化

    对于arguments,如果不是callback,也就是没有在url指定 xxx.0.callback=true这种的话,那么直接在hessian序列化

    public static Object encodeInvocationArgument(Channel channel, RpcInvocation inv, int paraIndex) throws IOException {
    // get URL directly
    URL url = inv.getInvoker() == null ? null : inv.getInvoker().getUrl();
    byte callbackstatus = isCallBack(url, inv.getMethodName(), paraIndex);
    Object[] args = inv.getArguments();
    Class<?>[] pts = inv.getParameterTypes();
    switch (callbackstatus) {
    case CallbackServiceCodec.CALLBACK_NONE:
    return args[paraIndex];
    case CallbackServiceCodec.CALLBACK_CREATE:
    inv.setAttachment(INV_ATT_CALLBACK_KEY + paraIndex, exportOrunexportCallbackService(channel, url, pts[paraIndex], args[paraIndex], true));
    return null;
    case CallbackServiceCodec.CALLBACK_DESTROY:
    inv.setAttachment(INV_ATT_CALLBACK_KEY + paraIndex, exportOrunexportCallbackService(channel, url, pts[paraIndex], args[paraIndex], false));
    return null;
    default:
    return args[paraIndex];
    }
    }

    那么如果是一个callback的话,return null没有在argument进行序列化,而是把一个callback实例通过exportOrunexportCallbackService放到attachment里面,具体这个exportOrunexportCallbackService干了啥呢?具体比较复杂,总结来说就是构造了一个新的dubboinvoer,这个invoker的interface就是这个callback的interface+hashcode(加hashcode考虑有多个interface的callback,他们在不同的方法上),他提供的方法就是这个callback要做的方法。

    也就是说消费者在把callback序列化的时候,实际上构造了一个dubboinvoker,等待提供者来调用。

    提供者在接收到消息的时候,对method-name、parameter-type进行反序列化,并且通过url知道哪些参数是一个callback,接着以这个远端的channel(在netty回调的时候decode方法可以轻松拿到这个channel)构造了一个referinvoker

    这个referinvoker就是对消费者callback的一个抽象,同样的这个invoker的interface就是这个callback的interface+hashcode(加hashcode考虑有多个interface的callback,他们在不同的方法上),他提供的方法就是这个callback要做的方法。

    也就是说提供者反序列化的时候,对这个callback实现了一个referinvoker,等到真正要调用这个callback的时候,虽然是本地执行,实际上是远程调用到消费者,而不是在本地执行callback。

    
    
  • 相关阅读:
    Codeforces Round #590 D. Distinct Characters Queries
    线段树模板加模板题POJ3468
    hihoCoder挑战赛5 C 与链
    HDU 5044 Tree 树链剖分
    HYSBZ 1901 Dynamic Rankings 树状数组套主席树
    POJ 2761 Feed the dogs 主席树
    POJ 2104 K-th Number 主席树 区间第K大
    HDU 4547 CD操作 LCA
    POJ 1470 Closest Common Ancestors 离线LCA
    HYSBZ 1036 树的统计Count 树链剖分 线段树
  • 原文地址:https://www.cnblogs.com/notlate/p/10228801.html
Copyright © 2011-2022 走看看