Transporters
Transporters该类是一种门面模式的设计,主要是解决和多个不同子模块直接进行交互的问题 , 通过该类设计,将公共的行为Transporter对象的创建以及ChannelHandler的处理,大家可以直接依赖Transporters类,这部分调用是在Dubbo协议初始化时候发起的,这部分我们到时候在细讲,这个章节暂时先不讲解 。但是这里需要在这个看一下关于ChannelHandler的处理,此处传入了多个ChannelHandler,将多个ChannelHandler包装成为ChannelHandlerDispatcher , ChannelHandlerDispatcher实现ChannelHandler,内部维护了一个 CopyOnWriteArraySet,对外提供操作ChannelHandler方法,此处主要是为了引出后续Handler的处理流程,后续一层处理模型的源头都在这里 。
到这里我们大概对Dubbo的通讯模型有了一个轮廓,我们来进行一个简单的总结,可以参考下图:
- 上层通过会Transporters获取到具体的Transporter扩展实现 , 然后通过Transporter获取Client和 RemotingServer实现;
- Client与RemotingServer都是通过Channel进行交互,Channel使用ChannelHandler进行数据传输 , 此外通过Codec2进行编解码;
AbstractChannelBufferAbstractChannelBuffer维护两类索引,一类用于读写,另外一类用于读写标记;关于读写类索引就是记录当前读到什么位置以及写到什么位置了,标记类索引就是为了做数据备份和回滚使用,为了对缓冲区重复利用 。该类的方法都主要是利用四个属性来操作,用来检测是否有数据可读或者还是否有空间可写等方法,做一些前置条件的校验以及索引的设置 , 具体的实现都是需要子类来实现 。
@Override public void readBytes(byte[] dst, int dstIndex, int length) { //检查位置是否足够 checkReadableBytes(length); //此处可以理解为将readerIndex后移length个字节读取到dst数组中 //也就是数组dst的dstIndex~dstIndex+length位置 getBytes(readerIndex, dst, dstIndex, length); //readerIndex后移length个字节 readerIndex += length; } @Override public void readBytes(byte[] dst, int dstIndex, int length) { //检查位置是否足够 checkReadableBytes(length); //此处可以理解为将readerIndex后移length个字节读取到dst数组中 //也就是数组dst的dstIndex~dstIndex+length位置 getBytes(readerIndex, dst, dstIndex, length); //readerIndex后移length个字节 readerIndex += length; } @Override public void writeBytes(byte[] src, int srcIndex, int length) { //将src数组中srcIndex~srcIndex+length位置的数据写到当前的buffer中 setBytes(writerIndex, src, srcIndex, length); //将当前的writerIndex后移length writerIndex += length; }HeapChannelBufferHeapChannelBuffer是ChannelBuffer的一种具体的实现,该类是基于字节数组的ChannelBuffer实现,通过byte[]数组来进行数据的存储 , setBytes和getBytes通过System.arraycopy来进行对数组的操作 。
//此缓冲区包装的基础堆字节数组 protected final byte[] array; @Override public void getBytes(int index, byte[] dst, int dstIndex, int length) { System.arraycopy(array, index, dst, dstIndex, length); } @Override public void setBytes(int index, byte[] src, int srcIndex, int length) { System.arraycopy(src, srcIndex, array, index, length); }
推荐阅读
- 驱动开发:内核封装WSK网络通信接口
- 二 Linux进程间通信
- 一 Linux进程间通信
- VS Code For Web 深入浅出 -- 进程间通信篇
- 聊聊Linux中CPU上下文切换
- 聊聊Vim的工作原理
- 驱动开发:通过Async反向与内核通信
- 今天聊聊跑步配速那些事 跑步机配速对照表
- 51单片机下实现软件模拟IIC通信
- 驱动通信:通过PIPE管道与内核层通信