有了一些Fix基本概念后,接下来继续学习Fix协议(主要来学习Session level协议),今天就以QuickFix的启动初始化来讲解,在QuickFix启动初始化其间,都涉及了哪些重要的Fix 协议内容.
名词:
Acceptor ,通信双方,服务器所在方initiator,通信双方,客户端所在方Fix connection (Fix连接),官方文档说明一般包括3个部分,登陆,交换信息,退出,个人觉得还应该包括物理网络连接.Fix Session(Fix 会话),官方文档说明Fix Session可以有一个或多个Fix connecion组成.即Fix session可以多次登陆.它是一个逻辑的概念.一个Fix Session一般会有几个重要标示以区分一个Fix Session,如,包含Fix版本号字符串(如:FIX.4.2),发送者ID,接受者ID等),这样Fix Session每发送一个消息时候,消息头里面的BeginString,SenderCompID,TargetCompID 被赋值.当消息通过Fix connecion的物理网络连接到达对端的时候,对端可以根据消息头里面的标示找到自己端的Fix Session去处理消息.
QuickFix 关键类:
1.quickfix.Application
quickfix.Application类型对象,因为quickfix.Application里面定义了几个方法
onCreate –>当一个Fix Session建立是调用
onLogon –>当一个Fix Session登录成功时候调用
onLogout –>当一个Fix Session退出时候调用
fromAdmin–>当收到一个消息,经过一系列检查,合格后,属于Admin 类型时候调用
fromApp–>当收到一个消息,经过一系列检查,合格后,不属于Admin 类型时候调用
toAdmin–>当发送一个admin类型消息调用
toApp—>当发送一个非admin(业务类型)消息调用
一般情况下,如果您的应用程序需要用到Quickfix 时候,你只需要定义自己的Application类,然后根据您自己的业务实现上述几个方法即可。
2. quickfix.MessageStoreFactory , quickfix.MessageStore
这2也是接口,主要用来给Fix Session持久化类型(如,用文件存储,数据存储,存储的内容包括,状态,创建时间,消息,及其自己维护的发送序列号和接受序列号等)
quickfix.MessageStoreFactory的有 quickfix.JdbcStoreFactory ,quickfix.FileStoreFactory 两个实现,
quickfix.MessageStore 也有2种实现。quickfix.JdbcStore,quickfix.FileStore .
其中JdbcStoreFactory 负责创建JdbcStore , FileStoreFactory负责创建FileStore
quickfix 默认用文件存储,因为文件存储效率高。
如果你想自定义持久方式,你可以自己定义MessageStoreFactory的实现,并且自定义一种MessageStore
3.quickfix.LogFactory ,quickfix.Log
这2个也是个接口,负责创建不同类型的Log日志。QuickFix 提供了3中实现
quickfix.ScreenLogFactory–>负责创建quickfix.ScreenLog,即日志输出在终端屏幕上。
quickfix.JdbcLogFactory–>负责创建quickfix.JdbcLog,即日志输出在数据库中.
quickfix.FileLogFactory–>负责创建quickfix.FileLog,即日志输出在文件系统中
如果你想自定义Log输出,就请自己定义一个LogFactory的实现和一个quickfix.Log实现。
4.quickfix.MessageFactory ,quickfix.Message
该接口负责创建 quickfix.Message ,由于Fix有多个版本,所以在Fix的不同版本有一个实现
quickfix.fix40.MessageFactory
quickfix.fix41.MessageFactory
quickfix.fix42.MessageFactory
quickfix.fix43.MessageFactory
quickfix.fix44.MessageFactory
quickfix.fixt11.MessageFactory
quickfix.fix50.MessageFactory
同时quickfix还提供了一个默认实现quickfix.DefaultMessageFactory,这个默认实现其实包括上面的7种实现,然后根据Fix的版本自动选用其中一种而已。
所以如果你的应用支持哪几种,就在DefaultMessageFactory 中加载几种就可以了。
5.quickfix.Message 这个是对fix 消息字符串的一个封装。
quickfix。Session 这个类是非常关键的类,其实如果你把这个类搞清楚了,基本就能把Fix协议的大部分内容搞清楚了。
这个类有2个主要的方法,next() ,此方法是定时运行的一个方法,它主要做的是,是否需要发心跳,是否需要发个TEST, 是否需要断开连接,如果是客户端还有是否需要产生LOGON.
另一个最重要的方法是next(Message message) ,这个方法是消息到达Fix Session 后调用处理的方法。这个方法里面做了大部分Fix 协议规定,所以后续有文章分解说明。
这里大体说明这个方法就是调用数据字典,验证消息的合法性,验证消息序列号,然后处理。
6.quickfix.DefaultSessionFactory 根据配置文件,创建相应的Fix Session
7.quickfix.mina.message.FIXMessageDecoder 消息编解码类,当一个Fix字符串通过网络传输到对端时候,对端就会调用这个类来解码,并做一些校验,比如消息体长度。
8.quickfix.mina.message.FIXMessageEncoder 消息编解码类,当一个消息要写入网络时候, 需要调用此类,变成支持的字符编码。
9.quickfix.mina.AbstractIoHandler 这个类主要是处理消息类,有消息到达的时候,需要经过解码器之后,符合条件,则调用此类进一步处理消息。
这个类有2个子类,quickfix.mina.initiator.InitiatorIoHandler 这个主要客户端处理消息的类,quickfix.mina.acceptor.AcceptorIoHandler这个主要服务器端处理消息的类。这2个子类最重要的功能就是当一个Fix Session建立后,让一个Fix Session关联一个物理网络输出流(即:quickfix.mina.IoSessionResponder) .用于每个Fix Seeion发消息
10. quickfix.SocketAcceptor ,quickfix.mina.acceptor.AbstractSocketAcceptor
这个是Acceptor端核心类,它由它负责根据配置文件调用默认DefaultSessionFactory创建所有本Acceptor所支持的Fix Session .
为每个Fix Session邦定到一个侦听的端口,同时为每一个Fix Session分配一个AcceptorIoHandler 去处理来自物理网络连接来的数据.
启动Fix Session 的定时任务器.( SessionTimerTask,这个是在quickfix.mina.SessionConnector里面的一个内部类)
11.quickfix.SocketInitiator,quickfix.mina.initiator.AbstractSocketInitiator
这两个类是Initiator端核心类,它负责调用默认DefaultSessionFactory创建所有本Initiator所支持的Fix Session .
为每个Fix Session分配一个IoSessionInitiator.
12. quickfix.mina.initiator.IoSessionInitiator这个类是Initiator端核心类,这个类和Fix Session一对一关系,这个类主要任务是发起物理网络连接.并每隔一段时间检查网络连接情况.如果有问题,会自动重新接,同时为每一个Fix Session分配一个InitiatorIoHandcler去处理来自物理网络连接来的数据.
13。quickfix.mina.SingleThreadedEventHandlingStrategy 这个类是用来处理所有Fix Session 消息调度的。这是用一个单线程来调度Fix Session 的next(Message)方法去处理每个Fix Seeion 队列消息。14.quickfix.mina.ThreadPerSessionEventHandlingStrategy 这个类是用来处理所有Fix Session 消息调度的。这是为每一个Fix Session分配一个线程来调度Fix Session 的next(Message)方法去处理每个Fix Seeion 队列消息。
好了,了解了关键类后,我们来看看这些类的具体调用初始化情况
1.Acceptor (服务器)
步骤 | |
准备 | |
建立自己的Application | Application application = new Application(settings); |
建立自己的消息存储工厂 | MessageStoreFactory messageStoreFactory = new FileStoreFactory(settings); |
建立日至打印工厂 | LogFactory logFactory = new ScreenLogFactory(true, true, true); |
建立消息工厂 | MessageFactory messageFactory = new DefaultMessageFactory(); |
新建SocketAcceptor,根据上面几个参数 | acceptor = new SocketAcceptor(application, messageStoreFactory, settings, logFactory, messageFactory);
|
启动 | |
SocketAcceptor 启动 (启动,包括下面几个主要动作) | SocketAcceptor.start(); |
–调用session工厂建Fix session | AbstractSocketAcceptor.createSessions |
–启动一个SessionTimerTask去每隔1秒钟让每个一个Fix Session 依次调用自己的next(), 因为每个Fix Session 的next()里面会有逻辑什么时候发logon ,test,logout,disconnec等消息. | AbstractSocketAcceptor.SessionTimerTask |
–为每个Fix Session注册个网络端口,并分配一个处理消息的 IoHandler | AbstractSocketAcceptor.startAcceptingConnections |
–启动消息处理线程( 默认是单线程,即用一个队列接收所有Fix Session的消息,然后由这个线程依次从这队列里面取出,交给各自Fix Session的next(Message)方法去处理. | SingleThreadedEventHandlingStrategy.blockInThread (默认是单线程) |
2. initiator(客户端)
步骤 | |
准备 | |
建立自己的Application | BanzaiApplication application = new BanzaiApplication(orderTableModel, executionTableModel); |
建立自己的消息存储工厂 | MessageStoreFactory messageStoreFactory = new FileStoreFactory(settings); |
建立日至打印工厂 | LogFactory logFactory = new ScreenLogFactory(true, true, true); |
建立消息工厂 | MessageFactory messageFactory = new DefaultMessageFactory(); |
新建SocketInitiator,根据上面几个参数 | initiator = new SocketInitiator(application, messageStoreFactory, settings, logFactory, messageFactory)
|
启动 | |
SocketInitiator启动 (启动,包括下面几个主要动作) | SocketInitiator.start(); |
–调用session工厂建Fix session | AbstractSocketInitiator.createSessions |
–启动一个SessionTimerTask去每隔1秒钟让每个一个Fix Session 依次调用自己的next(), 因为每个Fix Session 的next()里面会有逻辑什么时候发logon ,test,logout,disconnec等消息. | AbstractSocketInitiator.SessionTimerTask |
–为每个Fix Session注册个网络连接器 | AbstractSocketInitiator.createSessionInitiators |
–启动消息处理线程( 默认是单线程,即用一个队列接收所有Fix Session的消息,然后由这个线程依次从这队列里面取出,交给各自Fix Session的next(Message)方法去处理. | SingleThreadedEventHandlingStrategy.blockInThread (默认是单线程) |
总结启动初始化其间,都涉及了哪些重要的Fix 协议内容:
1. 不管是服务器,还是客户端在Fix Session初始化,即在session工厂建Fix session后都会检查Fix Session时间范围,如果Fix Session启动不是当天有效的Session ,则会重置Fix Session里面的发送序列号,和接收 序列号. (Fix 规定一个Fix Session 一般不超过24小时)
2. 通信双方建立物理连接,总是由客户端发起(Fix 规定)