apache dubbo 2.7.3 源代码片段 - dubbo这样映射请求响应关系

居于netty的全双工,dubbo这样映射请求响应,每次请求都都会生成一个reqId,并把关系维护在FUTURES,在请求时把reqId放入请求帧中发送到服务端,服务端在响应的时候会把reqId放回到响应帧,并发送到客户端,客户端会根据该reqId从FUTURES获取。

 

 

请求
org.apache.dubbo.remoting.exchange.support.header.HeaderExchangeChannel#request(java.lang.Object, int)
org.apache.dubbo.remoting.exchange.support.DefaultFuture#DefaultFuture

@Override
public CompletableFuture<Object> request(Object request, int timeout) throws RemotingException {
    if (closed) {
        throw new RemotingException(this.getLocalAddress(), null, "Failed to send request " + request + ", cause: The channel " + this + " is closed!");
    }

    // create request. 请求对象
    Request req = new Request();
    req.setVersion(Version.getProtocolVersion());
    req.setTwoWay(true);

    /*
        当交互协议是 dubbo 时
            request === org.apache.dubbo.rpc.RpcInvocation
     */
    req.setData(request); // 数据
    DefaultFuture future = DefaultFuture.newFuture(channel, req, timeout); // !!!
    try {
        channel.send(req); // !!!
    } catch (RemotingException e) {
        future.cancel();
        throw e;
    }
    return future;
}

响应

org.apache.dubbo.remoting.exchange.support.header.HeaderExchangeHandler#handleResponse

static void handleResponse(Channel channel, Response response) throws RemotingException {
    if (response != null && !response.isHeartbeat()) {
        DefaultFuture.received(channel, response); // !!!!
    }
}

 

模拟代码

package cn.java.dubbo.demo.internal;

import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.common.Version;
import org.apache.dubbo.remoting.Channel;
import org.apache.dubbo.remoting.exchange.Request;
import org.apache.dubbo.remoting.exchange.Response;
import org.apache.dubbo.remoting.exchange.support.DefaultFuture;
import org.apache.dubbo.remoting.transport.ChannelDelegate;

import java.util.concurrent.CompletableFuture;

/**
 */
@Slf4j
public class RequestResponseMappingTest {

    private static final int DEFAULT_TIMEOUT = 20 * 1000;

    /**
     * 通过请求Id来维护关系
     */
    public static void main(String[] args) {
        Channel channel = new ChannelDelegate();

        // 请求对象
        Request req = new Request();
        req.setVersion(Version.getProtocolVersion());
        req.setTwoWay(true);
        DefaultFuture future = DefaultFuture.newFuture(channel, req, DEFAULT_TIMEOUT);

        // 执行异步请求
        new Thread(new Runnable() {
            @Override
            public void run() {
                // 执行请求
                try {
                    Thread.sleep(5 * 1000L);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                // 接收
                long reqId = req.getId(); // 请求Id,从消息帧里面提取reqId
                Response response = new Response(reqId);
                response.setResult("this is result.");
                DefaultFuture.received(channel, response);
            }
        }).start();

        // 等待结果
        CompletableFuture<Object> responseFuture = future;
        responseFuture.whenComplete((resp, ex) -> {
            if (ex != null) {
                log.error("异常", ex);
            } else {
                log.info("resp = {}", resp);
            }
        });
    }
}

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值