QuickFix/J 源代码
三). 客户化FIX解析
基础知识:以下文章内容描述的前提是已经根据自己的业务规则,生成了符合要求的数据字典,并且使用QuickFix/J自带的 ant 的
jar target生成了客户化的协议解析代码。生成协议解析代码的流程和细节,请参考文章QuickFix/J 源代码研究(二)。
1. 在QuickFix/J的设计中,为了解除message
factory和相应的协议的解析代码的耦合关系,quickfix.DefaultMessageFactory会在runtime时使用
reflection动态发现解析协议的代码。因此,如果你有自定义的数据字典,并且已经根据该字典生成了解析该协议的代码,请别忘记在
DefaultMessageFactory中加入相应协议的消息工厂discoverFactory(beginString, factoryClassName)。
2.
DefaultMessageFactory有两个主要功能,一个是创建Message(根据beginString和msgType),另一个是创建
Group(根据beginString、msgType和correspondingFieldID)。相应的,根据数据字典生成的解析协议的代码中,
当然有MessageFactory了,而且这个MessageFactory当然会创建Message和Group。
3. DefaultMessageFactory创建Message时,首先根据beginString查找相应版本的消息工厂,找到了则create相应的Message,否则new一个默认的quickfix.Message。
4.
MessageCracker的用法。当自动生成解析协议的代码之后,肯定会生成对应版本的MessageCracker。仔细阅读这个新生成的
MessageCracker,你会发现其中有很多的onMessage方法内部没有实现,并且加入了默认的throw new
UnsupportedMessageType();语句。在实际使用中,用户需要创建自己的Application,并且extends
quickfix.MessageCracker implements
quickfix.Application。由于Override,这些throw new
UnsupportedMessageType自然会被屏蔽。
如果用户需要取到Message中的内容,做相应的业务逻辑,首先在用户的Application.fromApp中
crack(message, sessionId),crack类似message cracker的工厂,它根据message
header选择相应的message
cracker,然后回调相应的onMessage。onMessage正好在用户Application中Override实现。
5. 客户化协议的客户端Initiator实现总结
a) 创建处理类,extends MessageCracker implements quickfix.Application implements quickfix.ApplicationExtended
b) 在fromApp中添加crack(message, sessionId);
c) 对需要处理的消息实现相应的onMessage
d) 创建SocketInitiator实例,填入客户化的application,messageStoreFactory,settings,logFactory,messageFactory。
e) start initiator。
6. 如果想把收到的每个消息单独存成一个文件备份,比如dbf之类的,该如何实现?
a) 方案1. 实现自己的MessageStore。QuickFix/J中提供了现成的FileStore,可以将所有的消息存入同一个文件中。
b) 方案2. 在Application的fromApp接口中,获取相应的Message,提取所需要素,存盘。
两个方案的比较:方案2减少了一次从String到Message的解析,效率应该更高。因为MessageStore的输入是StringMessage,需要再次解析才能得到Message。
7. FIX标准协议中规定了消息(Message)应该都至少有一个字段(Field),如果在客户化自己的FIX协议解析时,发现某些Message没有字段,则需要解除QuickFix/J中对这个条件的限制,具体在quickfix.Dictionary。
- private void load(Document document, String msgtype, Node node) throws ConfigError {
- ...
- // if (fieldNodes.getLength() == 0) {
- // throw new ConfigError("No fields found: msgType=" + msgtype);
- // }
- ...
- }
8.
在QuickFix/J的实现中,关于不同版本的协议都有这样一个假设,就是如果Fix版本号小于等于"FIX.4.4"则是一种逻辑,大于FIX4.4
是一种逻辑。那么就需要注意在客户化时你定义的协议版本(即FIX的beginString)是多少,是不是从字符串比较的角度看小于等
于"FIX.4.4"。如果不是,则需要在诸多的地方更改QuickFix/J的逻辑。比如在quickfix.DataDictionary.load
中:
- private void load(InputStream inputStream) throws ConfigError {
- ...
- if (beginString.startsWith(FIXT_PREFIX) || beginString.compareTo(FixVersions.FIX50) < 0) {
- ...
- ...
- }
9. QuickFix/J在实现中,默认消息(Message)头(Header)中使用的时间都是UtcTimeStamp,如果在客户化中不使用UTC时间,而使用本地时间的化,
a)
添加本地时间的数据类型,比如LocalTimeStampField,可以仿照quickfix.UtcTimeStampField。其他还需要添加
跟本地时间相关的
LocalDateOnlyField,LocalTimeOnlyField,LocalTimeStampConverter,LocalDateOnlyConverter,LocalTimeOnlyConverter
b)
在使用TimeStamp的地方,添加版本判断,根据版本看是使用本地时间还是UTC时间。需要修改地方大概
有:Session.doTargetTooHigh,Session.generateSequenceReset,Session.initializeResendFields,Session.validatePossDup,Session.verify。
10.
QuickFix/J在实现中,心跳设置(HeartBtInt)由客户端(Initiator)决定,而STEP协议则规定心跳由服务器端
(Acceptor),这需要修改DefaultSessionFactory.create(sessionID,
settings)中关于角色和HeartBtInt的设置。并且还需要修改Session.nextLogon(message)中登陆之后读取
HeartBtInt并设置到state中的逻辑。
QuickFix/J 源代码的更多相关文章
- QuickFIX/J常见问题汇总
最近在搞QuickFIX/J,网上的资料不算很多,遇到一些简单的问题都需要google一阵才能找到解决方法,因此做点记录: 错误:Rejecting invalid message: quickfix ...
- 基于MINA框架快速开发网络应用程序
1.MINA框架简介 MINA(Multipurpose Infrastructure for Network Applications)是用于开发高性能和高可用性的网络应用程序的基础框架.通过使用M ...
- Mina笔记
1.MINA框架简介 MINA(Multipurpose Infrastructure for Network Applications)是用于开发高性能和高可用性的网络应用程序的基础框架.通过使用M ...
- P1435 回文字串
P1435 回文字串 题目背景 IOI2000第一题 题目描述 回文词是一种对称的字符串.任意给定一个字符串,通过插入若干字符,都可以变成回文词.此题的任务是,求出将给定字符串变成回文词所需要插入的最 ...
- Java迷宫代码,广度优先遍历,最短路径
使用一个队列,采用层层扩张的方式,寻找迷宫最优的路径信息,再用一个迷宫节点数组记录行走信息方向常量定义: public interface Constant { // 右方向 int RIGHT = ...
- [wikipedia] List of free and open-source software packages
List of free and open-source software packages From Wikipedia, the free encyclopedia This articl ...
- 【Java并发编程实战】-----“J.U.C”:CountDownlatch
上篇博文([Java并发编程实战]-----"J.U.C":CyclicBarrier)LZ介绍了CyclicBarrier.CyclicBarrier所描述的是"允许一 ...
- 【Java并发编程实战】-----“J.U.C”:ReentrantReadWriteLock
ReentrantLock实现了标准的互斥操作,也就是说在某一时刻只有有一个线程持有锁.ReentrantLock采用这种独占的保守锁直接,在一定程度上减低了吞吐量.在这种情况下任何的"读/ ...
- 优化IPOL网站中基于DCT(离散余弦变换)的图像去噪算法(附源代码)。
在您阅读本文前,先需要告诉你的是:即使是本文优化过的算法,DCT去噪的计算量依旧很大,请不要向这个算法提出实时运行的苛刻要求. 言归正传,在IPOL网站中有一篇基于DCT的图像去噪文章,具体的链接地址 ...
随机推荐
- word开发遇到的问题
1.系统不能安装多个office word版本,建议只安装一个2003版本,越完整越好. 2.安装时候ghost系统会遇到问题,由于很多组件没有完整的安装,因此缺少了很多安装时文件保护要进行提醒的dl ...
- SharePoint 2013 Error - TypeError: Unable to get property 'replace' of undefined or null reference
错误信息 TypeError: Unable to get property ‘replace’ of undefined or null referenceTypeError: Unable to ...
- 通过终端编译链接运行C文件
1.创建c文件 touch demo.c 2.编辑c代码 3.编译(预编译.检查语法.编译).链接 3.1.指令:cc -c demo.c 正常情况下,会生成一个demo.o的二进制文件(即:目标 ...
- 查看Android系统是User模式还是Eng模式
root@itek82_wet_kk:/ # cat default.prop # # ADDITIONAL_DEFAULT_PROPERTIES # ro.secure= ro.allow.mock ...
- 【C语言】C语言static和extern区别
目录: [static] [extern] 1.static · 定义一个内部函数/变量. · 声明一个内部函数/变量. 2.extern · 定义一个外部函数/变量. · 声明一个外部函数/变量. ...
- Android C代码回调java方法
本文将讲述下列三种C代码回调java方法 1.c代码回调java空方法 2.c代码回调java int类型参数方法 3.c代码回调javaString类型参数方法 方法都差不多,先看c代码回调java ...
- XML解析之SAX详解
XML解析之SAX详解 本文属于作者原创 http://www.cnblogs.com/ldnh/ XML解析的五个步骤 1.打开文档 (void)parserDidStartDocument:(NS ...
- 简单的ASP.NET Forms身份认证
读了几篇牛人的此方面的文章,自己也动手做了一下,就想有必要总结一下.当然我的文章质量自然不能与人家相比,只是写给从没有接触过这个知识点的朋友. 网站的身份认证我以前只知道session,偶然发现一些牛 ...
- IO流03--毕向东JAVA基础教程视频学习笔记
提要 16 读取转换流17 写入转换流18 流操作规律-119 流操作规律-220 改变标准输入输出设备21 异常的日志信息22 系统信息 16 读取转换流 字符流体系中的InputStreamRea ...
- oracle报错:ORA-00054: 资源正忙,要求指定 NOWAIT
ORA-00054: 资源正忙, 但指定以 NOWAIT 方式获取资源: --首先得到被锁对象的session_idselect session_id from v$locked_object; -- ...