QuickFIX/J 中断开连接的客户端的消息队列行为
Message queue behavior in QuickFIX/J for disconnected clients
我想澄清 QuickFIX/J
(FIX 4.2) 在以下情况下的行为。此 QuickFIX/J
通讯涉及两方:
- 一个客户端启动器,名为 I。
- 我们公司的接受者计划,称为 A。
当 I 登录到 A 时,他们交换带有标签 35=A
的 FIX 消息。连接建立后,I开始提交订单。然而,可能有一个点,I 意外断开连接,此时 A 决定为 [=48] 的所有未结订单发送取消=]I(这是有效的,因为 A 不知道为什么 I 失败或 I 会活着回来的)。
请注意,整个断开连接取消程序由 A 单独启动和处理 - 它从 A 启动onLogout(...)
方法并由其正常的订单管理机制处理。为 I 的每个未结订单生成一条 35=F
消息,并且在每次成功取消时生成一条 ExecutionReport
(35=8
)。
当 I 活着回来时,这些 ExecutionReport
s 必须以某种方式传递给 I 以便它意识到所有它之前的订单已被取消。我的印象是 QuickFIX/J
的消息队列实现无需应用程序级帮助即可处理此问题。所有 QuickFIX
消息都确保传递给对方 (http://permalink.gmane.org/gmane.comp.finance.quickfix.devel/169)。
但是,与我的理解相反,A 的 QuickFIX
日志中没有显示 ExecutionReport
,也没有传送到 I 当 I 重新连接时,导致 I 不知道其之前的订单已被取消。我注意到由于 QuickFIX/J
中 Session
的 sendRaw(Message message, int num)
方法的以下源代码,不会发生日志记录:
/**
* Send the message
*
* @param message is the message to send
* @param num is the seq num of the message to send, if 0, the next expected sender seqnum is used.
* @return
*/
private boolean sendRaw(Message message, int num) {
...
} else {
try {
application.toApp(message, sessionID);
} catch (final DoNotSend e) {
return false;
} catch (final Throwable t) {
logApplicationException("toApp()", t);
}
messageString = message.toString();
if (isLoggedOn()) { // happens only if session is connected
result = send(messageString); // logging happens within "send"
}
}
...
}
在为 I 的断开连接发起的取消生成 ExecutionReport
消息时会话未登录,因此它从未达到 send(messageString);
并且没有记录发生。我相信没有消息出于同样的原因排队(基于 I 活着回来时没有收到任何消息的事实)。
我们公司基于 QuickFIX/J
保证所有消息无损传送的信念进行了许多实施,但我对上述情况的观察表明情况并非如此。
当会话未登录时,QuickFIX/J
的消息队列在这种情况下的预期行为如何?它是应该无论如何都对消息进行排队,等待会话在将来再次可用时发送,还是在会话关闭期间停止排队?
这是我的 10 美分:当 QF/J 根据序列号和间隙填充保证活动 session 的消息传递时...
如果 session 丢失,则无法保证任何事情。一旦发现序列号不匹配,您需要做的是将您的发起者和接受者配置为在重新连接时填充间隙。嗯,你的 ResetOnDisconnect 标志在配置中说了什么? ResetOnLogout 怎么样?
我不认为 QF 中有 "queue" 的消息在等待 session,因为 session 可以迪斯科并且永远不会侦察意味着 QF 队列一直在填充,或永远活跃,这不是 QF 能够立即为每个人处理的事情。
如果你有迪斯科舞厅,你也不能使用 OnLogout 向断开连接的客户端发送执行报告!首先,并不总是在每个迪斯科舞厅都调用 OnLogout,其次,正如您所说,我们进入了 QF 内部,它找不到要向其发送消息的 session,所以它除外。我不希望 QF 内部队列为我处理这种情况。同样,保证交付是在连接启动时......这是一个依赖关系。但是,我 会 希望它被记录在某个地方。您的日志记录配置是什么?
我想你需要看看为什么:"When / comes back alive, these ExecutionReports must be delivered to / somehow so that it becomes aware all its previous orders have been cancelled." disco 上的所有订单不是都被取消了吗?为什么/需要确认?这是给定的,不是吗?这可能是您必须单独编码到 QF 基础的东西。
阅读this。
一些公司支持 LOGON
消息中的标签 35002
(断开连接时取消),可能的值:
- 0: 不使用 COD
- 1:仅在发送 "graceful" 注销时使用 COD
- 2:在任何 "network" 断开连接时使用 COD
- 3: 1 和 2
了解您的交易对手是否支持这一点。我没有检查 QuickFIX 支持,但您始终可以自己手动添加标签,或自定义您的 FIX 字典以支持该标签。
显然这经常被高频交易者使用。对这个行业不熟悉,所以在评论区提问
在 private boolean sendRaw(Message message, int num)
方法的末尾有这段代码:
if (num == 0) {
final int msgSeqNum = header.getInt(MsgSeqNum.FIELD);
if (persistMessages) {
state.set(msgSeqNum, messageString);
}
state.incrNextSenderMsgSeqNum();
}
如果会话未连接,state.set(msgSeqNum, messageString)
将调用 messageStore.set(sequence, message)
实际存储消息以供稍后传送。
据我所知,所有消息都将排队等待会话成功登录。
我想澄清 QuickFIX/J
(FIX 4.2) 在以下情况下的行为。此 QuickFIX/J
通讯涉及两方:
- 一个客户端启动器,名为 I。
- 我们公司的接受者计划,称为 A。
当 I 登录到 A 时,他们交换带有标签 35=A
的 FIX 消息。连接建立后,I开始提交订单。然而,可能有一个点,I 意外断开连接,此时 A 决定为 [=48] 的所有未结订单发送取消=]I(这是有效的,因为 A 不知道为什么 I 失败或 I 会活着回来的)。
请注意,整个断开连接取消程序由 A 单独启动和处理 - 它从 A 启动onLogout(...)
方法并由其正常的订单管理机制处理。为 I 的每个未结订单生成一条 35=F
消息,并且在每次成功取消时生成一条 ExecutionReport
(35=8
)。
当 I 活着回来时,这些 ExecutionReport
s 必须以某种方式传递给 I 以便它意识到所有它之前的订单已被取消。我的印象是 QuickFIX/J
的消息队列实现无需应用程序级帮助即可处理此问题。所有 QuickFIX
消息都确保传递给对方 (http://permalink.gmane.org/gmane.comp.finance.quickfix.devel/169)。
但是,与我的理解相反,A 的 QuickFIX
日志中没有显示 ExecutionReport
,也没有传送到 I 当 I 重新连接时,导致 I 不知道其之前的订单已被取消。我注意到由于 QuickFIX/J
中 Session
的 sendRaw(Message message, int num)
方法的以下源代码,不会发生日志记录:
/**
* Send the message
*
* @param message is the message to send
* @param num is the seq num of the message to send, if 0, the next expected sender seqnum is used.
* @return
*/
private boolean sendRaw(Message message, int num) {
...
} else {
try {
application.toApp(message, sessionID);
} catch (final DoNotSend e) {
return false;
} catch (final Throwable t) {
logApplicationException("toApp()", t);
}
messageString = message.toString();
if (isLoggedOn()) { // happens only if session is connected
result = send(messageString); // logging happens within "send"
}
}
...
}
在为 I 的断开连接发起的取消生成 ExecutionReport
消息时会话未登录,因此它从未达到 send(messageString);
并且没有记录发生。我相信没有消息出于同样的原因排队(基于 I 活着回来时没有收到任何消息的事实)。
我们公司基于 QuickFIX/J
保证所有消息无损传送的信念进行了许多实施,但我对上述情况的观察表明情况并非如此。
当会话未登录时,QuickFIX/J
的消息队列在这种情况下的预期行为如何?它是应该无论如何都对消息进行排队,等待会话在将来再次可用时发送,还是在会话关闭期间停止排队?
这是我的 10 美分:当 QF/J 根据序列号和间隙填充保证活动 session 的消息传递时...
如果 session 丢失,则无法保证任何事情。一旦发现序列号不匹配,您需要做的是将您的发起者和接受者配置为在重新连接时填充间隙。嗯,你的 ResetOnDisconnect 标志在配置中说了什么? ResetOnLogout 怎么样?
我不认为 QF 中有 "queue" 的消息在等待 session,因为 session 可以迪斯科并且永远不会侦察意味着 QF 队列一直在填充,或永远活跃,这不是 QF 能够立即为每个人处理的事情。
如果你有迪斯科舞厅,你也不能使用 OnLogout 向断开连接的客户端发送执行报告!首先,并不总是在每个迪斯科舞厅都调用 OnLogout,其次,正如您所说,我们进入了 QF 内部,它找不到要向其发送消息的 session,所以它除外。我不希望 QF 内部队列为我处理这种情况。同样,保证交付是在连接启动时......这是一个依赖关系。但是,我 会 希望它被记录在某个地方。您的日志记录配置是什么?
我想你需要看看为什么:"When / comes back alive, these ExecutionReports must be delivered to / somehow so that it becomes aware all its previous orders have been cancelled." disco 上的所有订单不是都被取消了吗?为什么/需要确认?这是给定的,不是吗?这可能是您必须单独编码到 QF 基础的东西。
阅读this。
一些公司支持 LOGON
消息中的标签 35002
(断开连接时取消),可能的值:
- 0: 不使用 COD
- 1:仅在发送 "graceful" 注销时使用 COD
- 2:在任何 "network" 断开连接时使用 COD
- 3: 1 和 2
了解您的交易对手是否支持这一点。我没有检查 QuickFIX 支持,但您始终可以自己手动添加标签,或自定义您的 FIX 字典以支持该标签。
显然这经常被高频交易者使用。对这个行业不熟悉,所以在评论区提问
在 private boolean sendRaw(Message message, int num)
方法的末尾有这段代码:
if (num == 0) {
final int msgSeqNum = header.getInt(MsgSeqNum.FIELD);
if (persistMessages) {
state.set(msgSeqNum, messageString);
}
state.incrNextSenderMsgSeqNum();
}
如果会话未连接,state.set(msgSeqNum, messageString)
将调用 messageStore.set(sequence, message)
实际存储消息以供稍后传送。
据我所知,所有消息都将排队等待会话成功登录。