Resending Messages : OnixS .NET FIX Engine
forwardResetting Message Sequence Numbers via ResetSeqNumFlag Field   Table of ContentMemory-based Session Storageforward
Resending Messages

When the Resend Request (2) message is received from the counterparty (e.g. due to a sequence number mismatch), MessageResending event is raised if an application has been previously subscribed to this event. Otherwise, the SequenceReset-GapFill (4) message will be sent instead of the requested message.

If the sent application-level message needs to be resent to the counterparty, then the AllowResending property of MessageResendingEventArgs parameter should be set to True while handling the event. Otherwise, the SequenceReset-GapFill (4) message will be sent instead (e.g. in case of an aged order).

The message, that is about to be resent, is available via Msg property of the MessageResendingEventArgs parameter.

There is one important parameter: ResendingQueueSize. This parameter will specify how much messages can be resend if counterparty will request them. For example, this parameter is set to 1000 and counterparty sends a ResendRequest message with sequence numbers rage 1-2000. In this case, the session will send a SequenceReset-GapFill (4) message for range 1-1000 and messages 1001-2000 will be resend. If this parameter will be zero, there are no messages will be resend.

In accordance with the FIX protocol there are two options for dealing with gaps:

  • Request all messages including the last message received.
  • Request for the specific message missed while maintaining an ordered list of all newer messages.

The default behavior of the FIX Engine corresponds to the first option. In this mode, when a sequence gap is detected, the FIX Engine sends Resend Request (2) for all messages and waits for the reply. All newer incoming messages are ignored until the reply is received. In order to report the new messages anyway you can use ReportNewMessagesWhileWaitingForMissedMessages property. After the reply is received (first message with the PossDupFlag (tag #43) flag), there should not be any newer original messages until all requested messages are received, otherwise each such a message will cause a new resend request. Therefore, it can increase the network load and make difficulties for the sequence synchronization.

In order to activate the second option of the resend functionality you need to set the RequestOnlyMissedMessages property to true. In this mode, when a sequence gap is detected, the FIX Engine sends the Resend Request (2) only for missed messages. All newer incoming messages are stored in the incoming message gap queue and they are processed when all requested messages are received. You can limit the size of this queue by the IncomingMessageGapQueueMaximumSize setting.

To check all aspects of the resend functionality one may run the ResendingMessages sample from the FIX Engine distribution package.

Example
C#
void OnMessageResending(object sender, MessageResendingEventArgs e)
{            
     Console.WriteLine("Resend request for message {0}", e.Msg);

     e.AllowResending = !IsStale(e.Msg);

     Console.WriteLine("AllowResending=" + e.AllowResending);
}

private bool IsStale(FIXForge.NET.FIX.Message message)
{
     // Simple sending time based filtering of stale messages.
     DateTime previousSendingTime = message.GetTimestamp(Tags.SendingTime);

     TimeSpan keepingTime = TimeSpan.FromMinutes(30);

     bool isStale = (DateTime.UtcNow - previousSendingTime) >= keepingTime;

     return isStale;

     // More advanced filtering could take into account the message type and/or application-level contents.
 }

 public void Run()
 {
   // .. 

   Session session = new Session("SenderCompID", "TargetCompID", ProtocolVersion.FIX44);
   session.MessageResending += new Session.MessageResendingEventHandler(OnMessageResending);

   // .. 
 }
VB
Sub OnMessageResending(ByVal sender As Object, ByVal e As MessageResendingEventArgs)
  Console.WriteLine("Message {0} is about to be resent to the counterparty", e.Msg)
  e.AllowResending = True
End Sub

Sub Run()
  ' ..
  Dim session As New Session("SenderCompID", "TargetCompID", ProtocolVersion.FIX44)
  AddHandler session.MessageResending, AddressOf OnMessageResending
  ' .. 
End Sub