QuickFix/J:ResendRequest ResetRequest

2023-11-02 19:44

本文主要是介绍QuickFix/J:ResendRequest ResetRequest,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

当接收到消息,取出msg tag=34,判断序列号与预期序列号是否一致,如果比预期的大,则会发送ResendRequest请求;如果比预期的小,则认为是发生了重大事故,则会发送logout发起断连。

所以,对于fix而言,接收的序列号过大时,是可自我修复的,而当序列号过小,则是属于重大事故,会断开连接,人工干预处理后再重连。

相关逻辑在Session.next(Message message, boolean isProcessingQueuedMessages)中:

private boolean doTargetTooLow(Message msg) throws FieldNotFound, IOException {//判断是否为重传消息,如果不是重传消息,则logout,并且抛出异常if (!isPossibleDuplicate(msg)) {final int msgSeqNum = msg.getHeader().getInt(MsgSeqNum.FIELD);final String text = "MsgSeqNum too low, expecting " + getExpectedTargetNum()+ " but received " + msgSeqNum;generateLogout(text);throw new SessionException(text);}//reset消息判断逻辑return validatePossDup(msg);
}private boolean validatePossDup(Message msg) throws FieldNotFound, IOException {final Message.Header header = msg.getHeader();final String msgType = header.getString(MsgType.FIELD);if (!MsgType.SEQUENCE_RESET.equals(msgType)) {if (header.isSetField(OrigSendingTime.FIELD)) {final LocalDateTime origSendingTime = header.getUtcTimeStamp(OrigSendingTime.FIELD);final LocalDateTime sendingTime = header.getUtcTimeStamp(SendingTime.FIELD);if (origSendingTime.compareTo(sendingTime) > 0) {generateReject(msg, BAD_TIME_REJ_REASON, OrigSendingTime.FIELD);generateLogout(BAD_ORIG_TIME_TEXT);return false;}} else {// QFJ-703if (requiresOrigSendingTime) {generateReject(msg, SessionRejectReason.REQUIRED_TAG_MISSING,OrigSendingTime.FIELD);return false;}}}return true;
}
private void doTargetTooHigh(Message msg) throws FieldNotFound, IOException, InvalidMessage {final Message.Header header = msg.getHeader();final String beginString = header.getString(BeginString.FIELD);final int msgSeqNum = header.getInt(MsgSeqNum.FIELD);getLog().onEvent("MsgSeqNum too high, expecting " + getExpectedTargetNum() + " but received "+ msgSeqNum + ": " + msg);enqueueMessage(msg, msgSeqNum);//判断是否正在重传(ResendRequest)中,避免消息的重复接收并处理if (state.isResendRequested()) {final ResendRange range = state.getResendRange();if (!redundantResentRequestsAllowed && msgSeqNum >= range.getBeginSeqNo()) {int endSeqNo = range.getEndSeqNo();String end = endSeqNo == 0 ? "infinity" : Integer.toString(endSeqNo);getLog().onEvent("Already sent ResendRequest FROM: " + range.getBeginSeqNo() + " TO: " + end+ ".  Not sending another.");return;}}//发起ResendRequestgenerateResendRequest(beginString, msgSeqNum);
}private void generateResendRequest(String beginString, int msgSeqNum) {final int beginSeqNo = getExpectedTargetNum();final int endSeqNo = msgSeqNum - 1;sendResendRequest(beginString, msgSeqNum, beginSeqNo, endSeqNo);
}

如果没有持久化消息,则只会发送resetRequest,只有持有化消息,才能重发消息。

如果是管理类消息(msgType=0A12345),一般都会跳过重传消息,除非ForceResendWhenCorruptedStore指定为true,其值默认为false。每次消息重传处理后,都会发送一次resetRequest,将对方的序列号重置为此次需发送的消息序列号+1,以与下次发送消息的序列号值匹配(递增)。

如下核心逻辑:

for (final String message : messages) {appMessageJustSent = false;final Message msg;try {// QFJ-626msg = parseMessage(message);msgSeqNum = msg.getHeader().getInt(MsgSeqNum.FIELD);} catch (final Exception e) {getLog().onErrorEvent("Error handling ResendRequest: failed to parse message (" + e.getMessage()+ "): " + message);// Note: a SequenceReset message will be generated to fill the gapcontinue;}if ((current != msgSeqNum) && begin == 0) {begin = current;}final String msgType = msg.getHeader().getString(MsgType.FIELD);//管理类消息,不会重传if (MessageUtils.isAdminMessage(msgType) && !forceResendWhenCorruptedStore) {if (begin == 0) {begin = msgSeqNum;}} else {//业务类消息,设置原发送时间(OrigSendingTime)、是否为重传消息(PossDupFlag)initializeResendFields(msg);if (resendApproved(msg)) {if (begin != 0) {generateSequenceReset(receivedMessage, begin, msgSeqNum);}getLog().onEvent("Resending message: " + msgSeqNum);send(msg.toString());begin = 0;appMessageJustSent = true;} else {if (begin == 0) {begin = msgSeqNum;}}}current = msgSeqNum + 1;
}

这篇关于QuickFix/J:ResendRequest ResetRequest的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/332880

相关文章

用Quickfix详解Fix(二)--运行源码

序言: 在初探Fix(一),我们运行了安装包自带的例子,本篇我们来一起让例子的程序源代码在Eclipse中运行起来,然后在以后的篇幅中,我会结合源代码来详细介绍Fix 协议的在QuickFix的实现。 准备: 1。下载安装Eclipse 。http://www.eclipse.org/downloads/ 2。 打开Eclipse,新建一个Java工程,如:myfix 3. 请把在Fix

用Quickfix详解Fix(一)--下载安装

(一) 前言 QuickFix 是Fix开源引擎,目前很多Fix解决方案都是根据或参考QuickFix实现的,尤其在中国市场,基本全部或大部分都是QuickFix的包装产品,所以QuickFix是作为学习Fix 的一个非常好的一个工具, 其官方网址为:http://www.quickfixengine.org , 目前有java,.Net,C++,Python和Ruby五种语言实现,可以说基

vim的quickfix模式

通常,我们在开发过程中,经常要写代码,编译,修改编译错误,这个过程会数十遍上百遍的重复。如果你是根据编译器输出的错误信息,打开出错的文件,找到出错的行,然后再开始修改,那效率未免太低下了。 利用vim的quickfix模式,可以大大加快这一过程,你可以在vim启动编译,然后vim会根据编译器输出的错误信息,自动跳到第一个出错的地方,让你进行修改;修改完后,使用一个快捷键,跳到下一个错误处,再进行

wingrep quickfix

:wingrep abc* :copen