protected bool HandleFIXLogin(MessageFIXT1_1 packet) { if (fixState != ServerState.Startup) { throw new InvalidOperationException("Invalid login request. Already logged in: \n" + packet); } fixState = ServerState.LoggedIn; SetupFixFactory(packet); simulators[SimulatorType.SendDisconnect].UpdateNext(FixFactory.LastSequence); simulators[SimulatorType.ReceiveDisconnect].UpdateNext(packet.Sequence); simulators[SimulatorType.SendServerOffline].UpdateNext(FixFactory.LastSequence); simulators[SimulatorType.ReceiveServerOffline].UpdateNext(packet.Sequence); simulators[SimulatorType.SystemOffline].UpdateNext(packet.Sequence); var mbtMsg = CreateLoginResponse(); if (debug) { log.Debug("Sending login response: " + mbtMsg); } SendMessage(mbtMsg); return(true); }
private bool HandleResend(MessageFIXT1_1 messageFIX) { int end = messageFIX.EndSeqNum == 0 ? FixFactory.LastSequence : messageFIX.EndSeqNum; if (debug) { log.Debug("Found resend request for " + messageFIX.BegSeqNum + " to " + end + ": " + messageFIX); } for (int i = messageFIX.BegSeqNum; i <= end; i++) { FIXTMessage1_1 textMessage; var gapFill = false; if (!FixFactory.TryGetHistory(i, out textMessage)) { gapFill = true; textMessage = GapFillMessage(i); } else { switch (textMessage.Type) { case "A": // Logon case "0": // Heartbeat case "1": // Heartbeat case "2": // Resend request. case "4": // Reset sequence. textMessage = GapFillMessage(i); gapFill = true; break; default: textMessage.SetDuplicate(true); break; } } if (gapFill) { if (debug) { var fixString = textMessage.ToString(); string view = fixString.Replace(FIXTBuffer.EndFieldStr, " "); log.Debug("Sending Gap Fill message " + i + ": \n" + view); } ResendMessageProtected(textMessage); } else { ResendMessage(textMessage); } } return(true); }
private bool HandleGapFill(MessageFIXT1_1 packetFIX) { if (!packetFIX.IsGapFill) { throw new InvalidOperationException("Only gap fill sequence reset supportted: \n" + packetFIX); } if (packetFIX.NewSeqNum <= RemoteSequence) // ResetSeqNo { throw new InvalidOperationException("Reset new sequence number must be greater than current sequence: " + RemoteSequence + ".\n" + packetFIX); } RemoteSequence = packetFIX.NewSeqNum; if (debug) { log.Debug("Received gap fill. Setting next sequence = " + RemoteSequence); } return(true); }
private bool Resend(MessageFIXT1_1 messageFix) { if (!isResendComplete) { return(true); } var mbtMsg = FixFactory.Create(); mbtMsg.AddHeader("2"); mbtMsg.SetBeginSeqNum(RemoteSequence); mbtMsg.SetEndSeqNum(0); if (debug) { log.Debug("Sending resend request: " + mbtMsg); } SendMessage(mbtMsg); return(true); }
protected virtual void SetupFixFactory(MessageFIXT1_1 packet) { if (packet.IsResetSeqNum) { if (packet.Sequence != 1) { throw new InvalidOperationException("Found reset sequence number flag is true but sequence was " + packet.Sequence + " instead of 1."); } if (debug) { log.Debug("Found reset seq number flag. Resetting seq number to " + packet.Sequence); } fixFactory = CreateFIXFactory(packet.Sequence, packet.Target, packet.Sender); RemoteSequence = packet.Sequence; } else if (FixFactory == null) { throw new InvalidOperationException( "FIX login message specified tried to continue with sequence number " + packet.Sequence + " but simulator has no sequence history."); } }
private bool ProcessMessage(MessageFIXT1_1 packetFIX) { if (isConnectionLost) { if (debug) { log.Debug("Ignoring message: " + packetFIX); } RemoveTickSync(packetFIX); return(true); } var simulator = simulators[SimulatorType.ReceiveDisconnect]; if (FixFactory != null && simulator.CheckSequence(packetFIX.Sequence)) { if (debug) { log.Debug("Ignoring message: " + packetFIX); } // Ignore this message. Pretend we never received it AND disconnect. // This will test the message recovery.) ProviderSimulator.SwitchBrokerState("disconnect", false); isConnectionLost = true; return(true); } if (simulateReceiveFailed && FixFactory != null && random.Next(50) == 1) { // Ignore this message. Pretend we never received it. // This will test the message recovery. if (debug) { log.Debug("Ignoring fix message sequence " + packetFIX.Sequence); } return(Resend(packetFIX)); } simulator = simulators[SimulatorType.ReceiveServerOffline]; if (IsRecovered && FixFactory != null && simulator.CheckSequence(packetFIX.Sequence)) { if (debug) { log.Debug("Skipping message: " + packetFIX); } ProviderSimulator.SwitchBrokerState("disconnect", false); ProviderSimulator.SetOrderServerOffline(); if (requestSessionStatus) { SendSessionStatus("3"); //offline } else { log.Info("RequestSessionStatus is false so not sending order server offline message."); } return(true); } simulator = simulators[SimulatorType.SystemOffline]; if (IsRecovered && FixFactory != null && simulator.CheckSequence(packetFIX.Sequence)) { SendSystemOffline(); return(true); } if (debug) { log.Debug("Processing message with " + packetFIX.Sequence + ". So updating remote sequence..."); } RemoteSequence = packetFIX.Sequence + 1; switch (packetFIX.MessageType) { case "G": case "D": simulator = simulators[SimulatorType.BlackHole]; break; case "F": simulator = simulators[SimulatorType.CancelBlackHole]; break; } if (FixFactory != null && simulator.CheckFrequency()) { if (debug) { log.Debug("Simulating order 'black hole' of 35=" + packetFIX.MessageType + " by incrementing sequence to " + RemoteSequence + " but ignoring message with sequence " + packetFIX.Sequence); } return(true); } ParseFIXMessage(_fixReadMessage); return(true); }
protected abstract void RemoveTickSync(MessageFIXT1_1 textMessage);