精尽 Dubbo 源码分析 —— NIO 服务器(四)之 Exchange 层

1.概述

exchange 信息交换层:封装请求响应模式,同步转异步,以 Request, Response 为中心,扩展接口为 Exchanger, ExchangeChannel, ExchangeClient, ExchangeServer。
类图:
在这里插入图片描述

2.ExchangeChannel

继承 Channel 接口,信息交换通道接口。方法如下:

/**
 * ExchangeChannel. (API/SPI, Prototype, ThreadSafe)
 *
 * 信息交换通道接口
 */
public interface ExchangeChannel extends Channel {

    /**
     * send request.
     *
     * 发送请求
     *
     * @param request 请求
     * @return response future
     * @throws RemotingException 远程调用,发生异常
     */
    ResponseFuture request(Object request) throws RemotingException;

    /**
     * send request.
     *
     * 发送请求
     *
     * @param request 请求
     * @param timeout 超时时长
     * @return response future
     * @throws RemotingException 远程调用,发生异常
     */
    ResponseFuture request(Object request, int timeout) throws RemotingException;

    /**
     * get message handler.
     *
     * 获得信息交换处理器
     *
     * @return message handler
     */
    ExchangeHandler getExchangeHandler();

    /**
     * graceful close.
     *
     * 优雅关闭
     *
     * @param timeout 超时时长
     */
    void close(int timeout);

}
2.1 HeaderExchangeChannel

现 ExchangeChannel 接口,基于消息头部( Header )的信息交换通道实现类。
构造方法:

/**
 * ExchangeReceiver
 *
 * 基于消息头部( Header )的信息交换通道实现类
 */
final class HeaderExchangeChannel implements ExchangeChannel {

    private static final Logger logger = LoggerFactory.getLogger(HeaderExchangeChannel.class);

    /**
     * 通道键
     */
    private static final String CHANNEL_KEY = HeaderExchangeChannel.class.getName() + ".CHANNEL";

    /**
     * 通道
     */
    private final Channel channel;
    /**
     * 是否关闭
     */
    private volatile boolean closed = false;

    HeaderExchangeChannel(Channel channel) {
        if (channel == null) {
            throw new IllegalArgumentException("channel == null");
        }
        this.channel = channel;
    }
}

getOrAddChannel(Channel) 静态方法,创建 HeaderExchangeChannel 对象。代码如下:

    /**
     * 创建 HeaderExchangeChannel 对象
     *
     * @param ch 通道
     * @return HeaderExchangeChannel 对象
     */
    static HeaderExchangeChannel getOrAddChannel(Channel ch) {
        if (ch == null) {
            return null;
        }
        HeaderExchangeChannel ret = (HeaderExchangeChannel) ch.getAttribute(CHANNEL_KEY);
        if (ret == null) {
            ret = new HeaderExchangeChannel(ch);
            if (ch.isConnected()) { // 已连接
                ch.setAttribute(CHANNEL_KEY, ret);
            }
        }
        return ret;
    }

发送请求:

    @Override
    public ResponseFuture 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("2.0.0");
        req.setTwoWay(true); // 需要响应
        req.setData(request);
        // 创建 DefaultFuture 对象
        DefaultFuture future = new DefaultFuture(channel, req, timeout);
        try {
            // 发送请求
            channel.send(req);
        } catch (RemotingException e) { // 发生异常,取消 DefaultFuture
            future.cancel();
            throw e;
        }
        // 返回 DefaultFuture 对象
        return future;
    }

优雅关闭:

    @Override
    public void close(int timeout) {
        if (closed) {
            return;
        }
        closed = true;
        // 等待请求完成
        if (timeout > 0) {
            long start = System.currentTimeMillis();
            while (DefaultFuture.hasFuture(channel) && System.currentTimeMillis() - start < timeout) {
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    logger.warn(e.getMessage(), e);
                }
            }
        }
        // 关闭通道
        close();
    }

3. ExchangeClient

Client ,ExchangeChannel 接口,信息交换客户端接口。
无自定义方法。

3.1 HeaderExchangeClien
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值