fdbus之CBaseMessage

总体介绍

这个类是一个很重要的的类,fdbus中传递对象就是这个类的实例,该类中包含了很多重要的信息。可以这样理解,再fdbus的通信中,这个类的地位至关重要。他们的通信的内容就是该类定义的一些信息。

虽然CFdbBaseObject定义了一些方法,例如invoke、publish等,但是需要指出的消息的实际发出动作都是由CBaseMessage发出的,我们应该这样理解CBaseMessage类,这个类不仅定义了消息的具体字段和结构,比如消息的结构,消息消息头的结构,内容等,还定义了消息的具体操作方法,比如消息的发送,序列化/反序列化等、以及消息的各个部分的偏移和长度等消息的具体信息。还有很多比如该消息是否是同步的,优先级如何等关于消息的所有信息和操作都被这个类持有,这是c++面向对象的核心思想。

消息结构

fdbus消息的结构,从CFdbMessage.h文件可以找到这个注释,通过这个注释我们了解到通信过程中消息的组织方式:

    /*
     *=========================================================
     * buffer structure:
     * +-----+-----+-------+--------------+----------+
     * |  1  |  2  |   3   |      4       |     5    |
     * +-----+-----+-------+--------------+----------+
     *
     * 1: offset; paddings
     * 2: prefix; 0 - 3 bytes: total length (2+3+4+5)
     *            4 - 7 bytes: length of head (3)
     * 3: head
     * 4: payload
     * 5: extra data
     */

  1. 第一部分是一个偏移,该偏移内部数值无效
  2. 第二部分是消息前缀,前缀包含两个字段,第一个字段占用4个字节,含义是总长度,该长度是第二、第三、第四、第五部分的长度之和;第二个字段也是占用4个字节,它的值为第三个部分的长度值。
  3. 第三部分是消息头部。
  4. 第四部分是消息负载,一般而言消息的具体内容会放在这部分
  5. 第五部分是额外数据,该部分内容我还没有搞清楚,可能会存放一些调试信息,例如时间戳之类的。

类图

fdbus之CBaseMessage_第1张图片

 方法介绍

这里将消息的操作分成几类,我这哩列出的可能不全,仅仅是将我认为重要的一些方法列出来。再我理解中分成三类:

  1. 消息发送方法,例如pubish、invoke、send、broadcast、subscribe等及dispatchMsg函数,dispatchMsg是一个重要的函数,该函数包含了一系列的发送相关的方法。
  2. 消息体构造方法:包括但不限于消息的组装方法例如buildHeader,deserialize,serialize等还,获取该消息的各个部分的偏移及长度等函数
  3. 消息接收处理函数:例如doRequest,doReply,doBroadcast,autoReply等

这里介绍一下CFunctionJob类,这个类是一个功能类,为CBaseMessage类提供了基础的JOB对象的操作方法,下面先介绍成员函数,再依据成员函数介绍这个类的作用。

  • setCallable:回调函数,每个job对象都会需要设置这个回调,在事件循环中会使用到这个方法
  • run:这是一个运行函数,当消息压入到队列中时,当遍历到该消息时,最终会通过调用run函数,而run方法则会调用setCallable方法设置的回调
  • mJobFunc:这是一个成员变量,该成员变量用于保存回调

这个类应该这样理解,job对象包含多种消息类型有的是broadcast,有的是REQUEST,有的是PUBLISH类型,每种类型的消息处理是不一样的,需要提供一个类告诉CBaseMessage这个JOB对象应该如何处理,而CFunctionJob这个类就是用于完成这个工作的。再事件循环中,遍历每个消息,然后调用runonejob函数,感兴趣的朋友可以看下。

成员介绍

该类中包含了很多数据成员,有很多我也搞不清楚到底啥作用,这里将自己知晓的列出来供大家参考:

  • mSn:消息序列号,每个消息都会分配一个,该序列号的作用是用于端点收到回复时判断是否是同一条消息。该字段由内部框架自动赋值,无需用户指定。
  • mCode:消息码,这个是用注册的消息码,由用户注定,用于表示消息类型。
  • mFilter:主题,个人理解是同一个消息码下可以利用该字段进行分支处理。
  • mSid:会话id
  • mType:消息的请求类型,要与mCode区分开,mCode是用户指定的,而mType是框架指定的,用于表面这个消息是什么操作,比如标识是BROADCAST/PUBLISH/REQUEST/REPLY等操作,便于框架进行处理;而mCode是由用户指定的,用户根据该字段的值进行特定的业务处理。
  • mBuffer:用于存储消息的缓存地址
  • mPayloadSize:消息负载的长度
  • mHeadSize:消息头的长度
  • mOffset:偏移的长度
  • mEpid:端点id,没记错的话应该是哪个端点发送,这个值就填哪个端点的值

我认为的一些比较重要点

在看fdbus源码的过程中,对于一个点迷惑了好长时间,就是调用invoke进行同步调用的情况下,用户线程是如何通过输入输出参数将获取到收到消息的内容的呢?搞了好久终于整明白了,这里记录一下,以免后续忘记。

这里只讲原理就不贴源码了,在讲之前首先要搞明白一个事情,会话(session)的作用,一个会话对应一个连接,一个连接对应一个socket,所以从这个角度来说消息的发送和接收都是通过CFdbSession类来实现的。这个类会调用CBaseMessage提供的方法解析消息,并保存到mbuffer中,然后再接收的某个阶段将mbuffer指向的消息地址赋值给原来同步调用线程中保存的CBaseJob::Ptr指向的对象下,这样就实现了同步调用情况下的参数既是输入参数,又是输出参数。

你可能感兴趣的:(fdbus,fdbus,中间件,rpc)