第7篇 rabbitmq 创建SocketFrameHandler

本节主要是熟悉socketFrameHandlerFactory类, 真正涉及到socket流处理器

  • 展示如下类图(我们本文关心是SocketFrameHandlerFactory 和SocketFrameHandler),由类图可以知道SocketFrameHandlerFactory继承抽象类AbstractFrameHandlerFactory, 抽象类实现FrameHandlerFactory接口
  • image-20210607174608720

1、FrameHandlerFactory (顶级接口)

  • 你可以看到它只有一个方法创建FrameHandler, 入参是地址和连接名称

    • FrameHandler create(Address addr, String connectionName) throws IOException;
      
  • 处理socket,必须创建socket对象,这就需要地址信息了,connectionName(连接名称)不是必要

1.1、Address地址对象

  • 它只有两个属性一个是_host 主机, _port 端口号
  • 主要方法就是解析ipv6(例如:[2001:db8:85a3:8d3:1319:8a2e:370:7348]:5671)的 host和port

1.2、FrameHandler (数据帧处理接口)

  • 它继承了NetworkConnection接口(主要地址相关的,获取本地地址和本地端口,以及地址和端口)
  • 实现类必须是线程安全的
  • com.rabbitmq.client.impl.FrameHandler#setTimeout ( 设置超时时间, 单位为毫秒)
  • com.rabbitmq.client.impl.FrameHandler#getTimeout (获取超时时间,单位为毫秒)
  • com.rabbitmq.client.impl.FrameHandler#sendHeader ( 设置请求头)
  • initialize() (初始化连接)
  • com.rabbitmq.client.impl.FrameHandler#readFrame (读取数据帧)
  • com.rabbitmq.client.impl.FrameHandler#writeFrame (写入数据帧)
  • com.rabbitmq.client.impl.FrameHandler#flush (刷新)
  • com.rabbitmq.client.impl.FrameHandler#close 关闭底层数据连接(没有实现Closeable接口)

2、AbstractFrameHandlerFactory 抽象类

  • 主要作用就是定义关于FrameHandlerFactory公共字段,其实很多地方也是这么用的,这个也是可以学习一下
  • 首先定义根据功能定义接口,第二步定义一个抽象类,把一个公共字段,还有可能模板方法写好,最后有子类进行实现
  • 能设置成final尽量设置成final
  • 成员变量
    • connectionTimeout 连接超时时间
    • configurator Socket 设置函数
    • ssl 是否ssl连接

3、SocketFrameHandlerFactory extend AbstractFrameHandlerFactory

3.1、成员变量

  • socketFactory socket工厂类
  • shutdownExecutor 关闭执行器
  • sslContextFactory ssl上下文工厂类

3.2、关键方法

  • com.rabbitmq.client.impl.SocketFrameHandlerFactory#create (创建处理器)

  • 流程如下所示

  • image-20210607192840575

  • 本质就是为创建socket对象,并将shutdownExecutor 封装成SocketFrameHandler对象,我们在3.3熟悉一下SocketFrameHandler

3.3、SocketFrameHandler implement FrameHandler

3.3.1、成员变量
  • _socket : socket对象

  • _shutdownExecutor 关闭执行器

  • _inputStream DataInputStream((BufferedInputStream))

    •         _inputStream = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
      
      
  • _outputStream DataOutputStream((BufferedOutputStream))

  • SOCKET_CLOSING_TIMEOUT=1指定强制关socket的逗留时间(单位为秒)

3.3.2、核心方法
  • com.rabbitmq.client.impl.SocketFrameHandler#sendHeader(设置请求头)

    • synchronized (_outputStream) {
                  _outputStream.write("AMQP".getBytes("US-ASCII"));
                  _outputStream.write(0);
                  _outputStream.write(major);
                  _outputStream.write(minor);
                  _outputStream.write(revision);
                  try {
                      _outputStream.flush();
                  } catch (SSLHandshakeException e) {
                      LOGGER.error("TLS connection failed: {}", e.getMessage());
                      throw e;
                  }
              }
      
    • 同步方法写入_outputStream,防止并发

    • AMQP采用是US-ASCII字符编码

    • 主要协商交互mq协议为 ( AMQP091)

  • com.rabbitmq.client.impl.SocketFrameHandler#initialize ( 开启监控socket 读取输入流)

    • 主要流程如下

    • image-20210607204159191

    • A、B、C、D 在下篇在串一下

  • com.rabbitmq.client.impl.SocketFrameHandler#close

    • 设置socket逗留时间为1秒
    • 使用shutdownExecutor执行 flush()方法(如果shutdownExecutor为空则手动调用flush方法, 异步Future task完成此项工作,防止写阻塞
    • 如果任务执行失败将考虑取消任务执行。
    • 最后再关闭socket

4、总结

  • 主要了解创建创建SocketFrameHandler类的过程,以及一些核心方法。类之间继承和实现
  • 一般会使用抽象接口定义公共属性和模板代码
  • 增加一个包装类,无非增加一些新能力和属性,数据形式转换

结尾

  • 感谢大家的耐心阅读,如有建议请私信或评论留言。
  • 如有收获,劳烦支持,关注、点赞、评论、收藏均可,博主会经常更新,与大家共同进步
  • 下一篇研究一下A,B,C,D具体处理逻辑
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值