quickfixgo 源代码剖析
quickfixgo 是 FIX 协议的 go 实现,本文是 v0.6.0 版本的源码阅读笔记。
基本架构
quickfixgo 提供了 Acceptor 结构。启动 Acceptor 进程将会监听指定端口(由配置的 SocketAcceptPort 指定),在此之前,Accecptor 会创建 Session (数量由配置中的 SESSION 一节指定,每个 SESSION 由 BeginString, SenderCompID 和 TargetCompID 确定1),Session 处理 FIX message 并返回处理结果(以 FIX message 的格式)。

如图所示,Acceptor.Start() 的时候,它会 fork 出 goroutine,在其中执行 Session.Run()。Session 会阻塞在一个 select 语句上,等待若干不同的 chan 输入数据。
初看 quickfixgo 源代码时,容易绕晕的是它的数据传递方式。在 Session.Run 之后,Acceptor 会监听 netConn,接收刀 FIX msg 时,创建两个 chan —— msgIn 与 msgOut。并将这两个 chan 发送到对应 Session 的 chan admin。admin 只会处理跟连接管理相关的信息,当它接收到 connect 类型的信息时,它会判断 Session 状态,然后将 Session 的 chan MessageIn 替换为传进来的 chan MsgIn2。之后 Acceptor 会 fork 出 goroutine,让 msgIn 在一个 readLoop 中不断接收信息,msgOut 不断写信息(Sesssion 会把结果写到 msgOut 中)。
这就是 quickfixgo 的基本架构,重点在于数据通过不同的 chan 在应用内部流动,有点绕——你很难直接通过代码跳转看清楚。
信息处理
Session 在 chan messageIn 取得 FIX message 之后,message 的处理工作由 stateMachine 接手,它首先检查时间(看是否在交易时间中),然后检查是已经连接。如果一切正常,它会从 messagePool 中取出一个 msg,然后用读取的 FIX message 数据填充这个 msg3。
quickfixgo 的 sessionState 是 interface{} 。它定义了:
inSession;latentState;logonState;logoutState;notSessionState;resendState;
这中间的状态转移还是蛮复杂的,上图并不能完整概括。概括来说就是初始状态是 latentState ,Connect 之后转入 logonState,在 logonState 中接收到 logon 信息,正常处理完(即完成登录流程)会进入 inSession。