jspurefix 5.10.5 → 5.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/README.md +70 -0
  2. package/dist/runtime/session-launcher.d.ts +2 -0
  3. package/dist/runtime/session-launcher.js +13 -0
  4. package/dist/runtime/session-launcher.js.map +1 -1
  5. package/dist/transport/ascii/ascii-session-msg-factory.d.ts +1 -1
  6. package/dist/transport/ascii/ascii-session-msg-factory.js +2 -2
  7. package/dist/transport/ascii/ascii-session-msg-factory.js.map +1 -1
  8. package/dist/transport/ascii/ascii-session.d.ts +6 -0
  9. package/dist/transport/ascii/ascii-session.js +72 -8
  10. package/dist/transport/ascii/ascii-session.js.map +1 -1
  11. package/dist/transport/msg-application.d.ts +3 -0
  12. package/dist/transport/msg-application.js.map +1 -1
  13. package/dist/transport/session/fix-session.d.ts +1 -1
  14. package/dist/transport/session/fix-session.js.map +1 -1
  15. package/dist/transport/tcp/recovering-tcp-initiator.d.ts +6 -0
  16. package/dist/transport/tcp/recovering-tcp-initiator.js +55 -15
  17. package/dist/transport/tcp/recovering-tcp-initiator.js.map +1 -1
  18. package/dist/transport/tcp/tcp-initiator-connector.d.ts +2 -0
  19. package/dist/transport/tcp/tcp-initiator-connector.js +8 -3
  20. package/dist/transport/tcp/tcp-initiator-connector.js.map +1 -1
  21. package/dist/transport/tcp/tcp-initiator.d.ts +1 -0
  22. package/dist/transport/tcp/tcp-initiator.js +7 -40
  23. package/dist/transport/tcp/tcp-initiator.js.map +1 -1
  24. package/jsfix.test_client.txt +62 -62
  25. package/jsfix.test_server.txt +72 -72
  26. package/package.json +1 -1
  27. package/src/runtime/session-launcher.ts +25 -3
  28. package/src/transport/ascii/ascii-session-msg-factory.ts +8 -2
  29. package/src/transport/ascii/ascii-session.ts +115 -7
  30. package/src/transport/msg-application.ts +16 -0
  31. package/src/transport/session/fix-session.ts +12 -2
  32. package/src/transport/tcp/recovering-tcp-initiator.ts +74 -13
  33. package/src/transport/tcp/tcp-initiator-connector.ts +6 -1
  34. package/src/transport/tcp/tcp-initiator.ts +12 -6
@@ -1 +1 @@
1
- {"version":3,"file":"ascii-session.js","sourceRoot":"","sources":["../../../src/transport/ascii/ascii-session.ts"],"names":[],"mappings":"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","sourcesContent":["import { MsgView } from '../../buffer'\nimport { MsgTag, MsgType, SessionRejectReason } from '../../types'\nimport { IJsFixConfig } from '../../config'\nimport { FixSession } from '../session/fix-session'\nimport {\n FixMsgAsciiStoreResend, FixMsgMemoryStore, FixMsgStoreRecord,\n IFixMsgStore, IFixMsgStoreRecord,\n IFixSessionStore, IFixSessionStoreFactory,\n MemorySessionStore, MemorySessionStoreFactory, FileSessionStoreFactory, SessionId\n} from '../../store'\nimport { asMutable } from '../session/clone-session-description'\nimport { SessionState } from '../tcp'\nimport { TickAction } from '../tick-action'\nimport { IMsgApplication } from '../msg-application'\nimport { SegmentType } from '../../buffer/segment/segment-type'\nimport { SessionSequenceCoordinator } from '../session/session-sequence-coordinator'\nimport { DefaultFixClock } from '../session/fix-clock'\nimport { ResendActionType } from '../session/resend-request-manager'\nimport { AsciiMsgTransmitter } from './ascii-msg-transmitter'\nimport { MsgTransport } from '../factory'\nimport { ILooseObject } from '../../collections/collection'\n\nexport abstract class AsciiSession extends FixSession {\n /**\n * TargetCompID value which tells an acceptor to take its target from whichever\n * counterparty logs on, rather than from static configuration.\n */\n public static readonly WildcardCompId = '*'\n public heartbeat: boolean = true\n protected store: IFixMsgStore | null = null\n protected resender: FixMsgAsciiStoreResend\n protected coordinator: SessionSequenceCoordinator\n protected sessionStore: IFixSessionStore\n protected sessionId: SessionId\n private registered: boolean = false\n /** acceptor configured with TargetCompID '*' - identity comes from the peer Logon */\n protected readonly wildcardTarget: boolean\n private identityBound: boolean\n private bindInProgress: boolean = false\n private readonly pendingRx: Array<{ msgType: string, view: MsgView }> = []\n private readonly clock: DefaultFixClock = new DefaultFixClock()\n\n protected constructor (public readonly config: IJsFixConfig) {\n super(config)\n this.requestLogoutType = this.respondLogoutType = MsgType.Logout\n this.requestLogonType = MsgType.Logon\n this.store = new FixMsgMemoryStore(this.config.description.SenderCompId, this.config)\n this.resender = new FixMsgAsciiStoreResend(this.store, this.config)\n\n // A wildcard TargetCompID lets one acceptor serve counterparties it was not\n // statically configured for - the peer's SenderCompID becomes our target, and\n // therefore our SessionId and store, once the Logon arrives. An initiator has\n // to know who it is calling, so '*' is meaningless there.\n this.wildcardTarget = config.description.TargetCompID === AsciiSession.WildcardCompId\n if (this.wildcardTarget && this.initiator) {\n throw new Error(`TargetCompID '${AsciiSession.WildcardCompId}' is only valid for acceptors, not initiators`)\n }\n this.identityBound = !this.wildcardTarget\n\n this.sessionId = new SessionId(\n config.description.BeginString,\n config.description.SenderCompId,\n config.description.TargetCompID\n )\n // Until the peer identifies itself there is nothing worth persisting, so a\n // wildcard session starts on a throwaway in-memory store. The real store -\n // keyed on the peer's comp id - is created by bindIdentity.\n this.sessionStore = this.wildcardTarget\n ? new MemorySessionStore(this.sessionId)\n : this.storeFactory().create(this.sessionId)\n\n this.coordinator = new SessionSequenceCoordinator(this.sessionStore, this.clock)\n const lastReceivedSeqNum = config.description.LastReceivedSeqNum ?? 0\n this.coordinator.initializeFromConfig(undefined, lastReceivedSeqNum + 1)\n }\n\n private storeFactory (): IFixSessionStoreFactory {\n // Priority: programmatic config > JSON store config > default in-memory\n return this.config.sessionStoreFactory ?? AsciiSession.createStoreFactory(this.config.description.store)\n }\n\n /**\n * Initialize the session store (reads persisted sequences from file if using FileSessionStore),\n * sync the coordinator and transmitter from the store, then start the session.\n *\n * The transport's readable stream is paused during async store initialization to prevent\n * the AsciiParser (which starts reading immediately in its constructor) from consuming\n * and emitting messages before subscribe() hooks up the message handler.\n */\n public async run (transport: MsgTransport): Promise<number> {\n // Pause the readable stream to prevent data loss during async init.\n // The AsciiParser starts reading from the socket in its constructor,\n // but FixSession.subscribe() hasn't been called yet. Without pausing,\n // the client's Logon can arrive and be parsed into the void.\n transport.duplex.readable?.pause()\n\n if (this.wildcardTarget && !this.identityBound) {\n // Nothing to recover yet - the SessionId is not known until the peer logs on,\n // so store initialisation, sequence sync and registry claim all happen in\n // bindIdentity. Resume and wait for the Logon.\n this.sessionLogger.info('wildcard acceptor: awaiting peer Logon to establish session identity')\n transport.duplex.readable?.resume()\n return await super.run(transport)\n }\n\n // Initialize store — reads persisted .seqnums file if using FileSessionStore.\n // For MemorySessionStore this is a no-op.\n await this.sessionStore.initialize()\n\n // Coordinator becomes the source of truth for sequences\n this.coordinator.initializeFromStore()\n\n // Sync encoder's outgoing sequence from the store\n const transmitter = transport.transmitter as AsciiMsgTransmitter\n transmitter.msgSeqNum = this.coordinator.nextSenderSeqNum\n\n // Sync session state's last received sequence from the store\n this.sessionState.lastPeerMsgSeqNum = this.coordinator.lastProcessedPeerSeqNum\n\n this.sessionLogger.info(`store initialized: nextSender=${this.coordinator.nextSenderSeqNum}, expectedTarget=${this.coordinator.expectedTargetSeqNum}`)\n\n // Claim this SessionId. A counterparty which reconnected before its previous\n // socket was detected as dead would otherwise leave two live sessions writing\n // to one store - see issue #153.\n this.claimSessionId()\n\n // Resume the stream — super.run() will call subscribe() to hook up the message handler,\n // then the buffered data (including the client's Logon) will be delivered.\n transport.duplex.readable?.resume()\n\n return await super.run(transport)\n }\n\n private checkSeqNo (msgType: string, view: MsgView): boolean {\n switch (msgType) {\n case MsgType.SequenceReset: {\n return true\n }\n\n case MsgType.Logon: {\n // If peer sends ResetSeqNumFlag=Y, accept any sequence number.\n // PeerLogon handles the full sequence reset.\n if (view.getTyped(MsgTag.ResetSeqNumFlag) === true) {\n this.sessionLogger.info('logon with ResetSeqNumFlag=Y, accepting regardless of sequence')\n const seqNo = view.getTyped(MsgTag.MsgSeqNum) as number\n this.sessionState.lastPeerMsgSeqNum = seqNo\n this.coordinator.onMessageReceived(seqNo, false).catch((e: Error) => {\n this.sessionLogger.warning(`coordinator.onMessageReceived store persist failed: ${e.message}`)\n })\n return true\n }\n }\n // falls through\n\n default: {\n const state = this.sessionState\n const lastSeq: number = state.lastPeerMsgSeqNum\n const seqNo: number = view.getTyped(MsgTag.MsgSeqNum) as number\n let ret: boolean = false\n const seqDelta: number = seqNo - lastSeq\n if (seqDelta <= 0) {\n // Check if this is a PossDupFlag=Y message (resend replay) before rejecting.\n // PossDupFlag messages have old sequence numbers and bypass normal checks.\n const possDupFlag = view.getTyped(MsgTag.PossDupFlag) as boolean | undefined\n if (possDupFlag === true) {\n this.sessionLogger.debug(`message '${msgType}' has PossDupFlag=Y, bypassing sequence check`)\n this.coordinator.onMessageReceived(seqNo, true).catch((e: Error) => {\n this.sessionLogger.warning(`coordinator.onMessageReceived store persist failed: ${e.message}`)\n })\n return true\n }\n // Check if this is a delayed message that fills a pending gap range.\n const pendingRequests = this.coordinator.pendingResendRequests\n const inPendingGapRange = pendingRequests.some(p => seqNo >= p.begin && seqNo <= p.end)\n if (inPendingGapRange) {\n this.sessionLogger.info(`accepting delayed message seq ${seqNo} (in pending gap range)`)\n this.coordinator.onMessageReceived(seqNo, false).catch((e: Error) => {\n this.sessionLogger.warning(`coordinator.onMessageReceived store persist failed: ${e.message}`)\n })\n return true\n }\n // serious problem ... drop immediately\n this.sessionLogger.warning(`terminate as seqDelta (${seqDelta}) < 0 lastSeq = ${lastSeq} seqNo = ${seqNo}`)\n this.stop()\n } else if (seqDelta > 1) {\n // resend request required as have missed messages.\n const expectedSeq = lastSeq + 1\n\n // We process a Logon beforehand to confirm the connection even we out of sync\n if (msgType === MsgType.Logon) {\n this.peerLogon(view)\n }\n // If the out of sync message is a resend request itself, then we handle it first in order\n // to avoid triggering an endless loop of both sides sending resend requests in response to resend requests.\n if (msgType === MsgType.ResendRequest) {\n this.onResendRequest(view)\n }\n\n // Use coordinator to determine what action to take for the gap\n const action = this.coordinator.onGapDetected(expectedSeq, seqNo)\n this.sessionLogger.info(`gap action: ${action}`)\n\n switch (action.type) {\n case ResendActionType.SendResendRequest: {\n if (action.begin != null && action.end != null) {\n this.sendResendRequest(lastSeq, seqNo)\n this.coordinator.recordResendRequestSent(action.begin, action.end)\n }\n break\n }\n case ResendActionType.Wait: {\n this.sessionLogger.info(`waiting for existing resend request: ${action.reason}`)\n break\n }\n case ResendActionType.SendGapFill: {\n this.sessionLogger.warning(`gap recovery abandoned (storm protection): ${action.reason}`)\n break\n }\n }\n\n // Update sequence state regardless — the gap-triggering message is valid.\n state.lastPeerMsgSeqNum = seqNo\n this.coordinator.onMessageReceived(seqNo, false).catch((e: Error) => {\n this.sessionLogger.warning(`coordinator.onMessageReceived store persist failed: ${e.message}`)\n })\n\n // Logon and ResendRequest were already fully handled above (peerLogon / onResendRequest).\n // Don't return true for them — they must not be dispatched to onSessionMsg again.\n // Application messages (and everything else) should be forwarded normally.\n if (msgType !== MsgType.Logon && msgType !== MsgType.ResendRequest) {\n ret = true\n }\n } else {\n ret = true\n state.lastPeerMsgSeqNum = seqNo\n this.coordinator.onMessageReceived(seqNo, false).catch((e: Error) => {\n this.sessionLogger.warning(`coordinator.onMessageReceived store persist failed: ${e.message}`)\n })\n }\n\n // Reset timeout recovery on successful message receipt\n if (ret) {\n this.coordinator.resetTimeoutRecovery()\n }\n return ret\n }\n }\n }\n\n protected checkForwardMsg (msgType: string, view: MsgView): void {\n const okToForward = this.validStateApplicationMsg()\n if (okToForward) {\n this.sessionLogger.info(`ascii forwarding msgType = '${msgType}' to application`)\n this.setState(SessionState.ActiveNormalSession)\n this.onApplicationMsg(msgType, view)\n } else {\n this.terminate(new Error(`msgType ${msgType} received in state ${this.stateString()}`))\n }\n }\n\n private sendReject (msgType: string, seqNo: number, msg: string, reason: number): void {\n const factory = this.config.factory\n const reject = factory?.reject(msgType, seqNo, msg, reason)\n if (reject) {\n this.sessionLogger.warning(`rejecting with ${JSON.stringify(reject)}`)\n this.send(MsgType.Reject, reject)\n }\n }\n\n protected sendResendRequest (lastSeq: number, receivedSeq: number): void {\n const resend = this.config.factory?.resendRequest(lastSeq + 1, 0)\n if (resend) {\n this.sessionLogger.warning(`received seq ${receivedSeq}, but last known seq is ${lastSeq}. Sending resend request for all messages > ${lastSeq}`)\n this.send(MsgType.ResendRequest, resend)\n }\n }\n\n private checkIntegrity (msgType: string, view: MsgView): boolean {\n const state = this.sessionState\n const seqNum = view.getTyped(MsgTag.MsgSeqNum) as number\n\n const received: number = parseInt(view.getString(MsgTag.CheckSum) ?? '', 10)\n const computed = view.checksum()\n if (received !== computed) {\n const msg: string = `msgType ${msgType} checksum failed. received = ${received} computed = ${computed}`\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.ValueIsIncorrect)\n return false\n }\n\n if (view.segment.type === SegmentType.Unknown) {\n const msg: string = `msgType ${msgType} unknown`\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.InvalidMsgType)\n return false\n }\n\n const invalid = view.invalid()\n if (invalid.length > 0) {\n const msg: string = `msgType ${msgType} invalid tag${invalid.length > 1 ? 's' : ''} ${invalid.join(', ')}`\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.InvalidTagNumber)\n return false\n }\n\n const undefinedMsg: string | null = view.undefinedForMsg()\n if (undefinedMsg) {\n const msg: string = `msgType ${msgType} ${undefinedMsg}`\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.TagNotDefinedForThisMessageType)\n return false\n }\n\n const missingRequired = view.missing()\n if (missingRequired.length > 0) {\n const msg: string = `msgType ${msgType} missing required tag${missingRequired.length > 1 ? 's' : ''} ${missingRequired.join(', ')}`\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.RequiredTagMissing)\n return false\n }\n\n switch (state.state) {\n case SessionState.InitiationLogonReceived:\n case SessionState.InitiationLogonResponse: {\n const targetCompId = view.getString(MsgTag.TargetCompID)\n if (targetCompId !== state.compId) {\n const msg: string = `msgType ${msgType} unexpected TargetCompID ${targetCompId} expecting ${state.compId})`\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.CompIDProblem)\n return false\n }\n\n const peerCompId = view.getString(MsgTag.SenderCompID)\n if (peerCompId !== state.peerCompId) {\n const msg: string = `msgType ${msgType} unexpected SenderCompID ${peerCompId} expecting ${state.compId}`\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.CompIDProblem)\n return false\n }\n }\n break\n\n default: {\n break\n }\n }\n\n return true\n }\n\n /**\n * Override to resend stored messages following a sequence reset.\n * @protected\n */\n protected onResendRequest (view: MsgView): void {\n // if no records are in store then send a gap fill for entire sequence\n this.setState(SessionState.HandleResendRequest)\n const [beginSeqNo, requestedEndSeqNo] = view.getTypedTags([MsgTag.BeginSeqNo, MsgTag.EndSeqNo])\n const endSeqNo = requestedEndSeqNo === 0\n ? this.sessionState.lastSentSeqNum()\n : requestedEndSeqNo\n\n this.sessionLogger.info(`onResendRequest getResendRequest beginSeqNo = ${beginSeqNo}, endSeqNo = ${endSeqNo}`)\n this.resender.getResendRequest(beginSeqNo as number, endSeqNo as number).then((records: IFixMsgStoreRecord[]) => {\n const validRecords = records.filter(rec => rec.obj !== null)\n this.sessionLogger.info(`sending ${validRecords.length}`)\n validRecords.forEach(rec => {\n if (rec.obj) {\n this.send(rec.msgType, rec.obj)\n }\n })\n this.setState(SessionState.ActiveNormalSession)\n }).catch((e: Error) => {\n this.sessionLogger.error(e)\n })\n }\n\n protected override onPrepareForReconnect (): void {\n this.coordinator.prepareForReconnect()\n this.sessionLogger.info('coordinator reset transient state for reconnect')\n }\n\n /**\n * Take ownership of this SessionId in the registry, stopping whatever session\n * held it before. Idempotent - a session reused across reconnects (the\n * RecoveringTcpInitiator pattern) simply re-registers itself.\n */\n private claimSessionId (): void {\n const registry = this.config.sessionRegistry\n if (!registry) return\n const stoppedOld = registry.register(this.sessionId, this)\n if (stoppedOld) {\n this.sessionLogger.info(`session registry stopped previous session for ${this.sessionId.toString()}`)\n }\n this.registered = true\n }\n\n protected override onSessionStopping (): void {\n super.onSessionStopping()\n const registry = this.config.sessionRegistry\n if (!registry || !this.registered) return\n this.registered = false\n this.sessionLogger.info(`session stopping - unregistering from registry: ${this.sessionId.toString()}`)\n registry.unregister(this.sessionId, this)\n }\n\n protected override async onPreLogon (): Promise<void> {\n if (!this.config.description.ResetSeqNumFlag) return\n\n this.sessionLogger.info('initiator has ResetSeqNumFlag=Y, resetting sequences before logon')\n await this.coordinator.resetSession('initiator ResetSeqNumFlag=Y')\n\n const transmitter = this.transport?.transmitter as AsciiMsgTransmitter | undefined\n if (transmitter) {\n transmitter.msgSeqNum = this.coordinator.nextSenderSeqNum\n }\n this.sessionState.lastPeerMsgSeqNum = this.coordinator.lastProcessedPeerSeqNum\n\n if (this.store) {\n this.store.clear().catch((e: Error) => {\n this.sessionLogger.warning(`store.clear failed: ${e.message}`)\n })\n this.resender = new FixMsgAsciiStoreResend(this.store, this.config)\n }\n\n this.sessionLogger.info(`pre-logon reset complete: encoderSeqNum=${transmitter?.msgSeqNum}`)\n }\n\n protected override txOnEncoded (msgType: string, data: string, hdr: ILooseObject): void {\n super.txOnEncoded(msgType, data, hdr)\n // Store the encoded message in the session store for recovery/resend\n const seqNum = hdr?.MsgSeqNum as number | undefined\n if (seqNum != null) {\n const record = new FixMsgStoreRecord(msgType, new Date(), seqNum, undefined, data)\n this.sessionStore.put(record).catch((e: Error) => {\n // Never block sends on store errors\n this.sessionLogger.warning(`failed to store message seq=${seqNum}: ${e.message}`)\n })\n // Update store's sender sequence number (next outgoing seq = seqNum + 1)\n this.sessionStore.setSenderSeqNum(seqNum + 1).catch((e: Error) => {\n this.sessionLogger.warning(`failed to update sender seq: ${e.message}`)\n })\n }\n }\n\n private static readonly MaxLogonRetries = 100\n private static readonly MaxTimeoutRecoveryAttempts = 0\n\n private static createStoreFactory (storeConfig?: { type: string, directory?: string }): IFixSessionStoreFactory {\n if (!storeConfig) return new MemorySessionStoreFactory()\n switch (storeConfig.type?.toLowerCase()) {\n case 'file':\n return new FileSessionStoreFactory(storeConfig.directory ?? 'store')\n default:\n return new MemorySessionStoreFactory()\n }\n }\n\n private handleLogonRejected (text: string | null): void {\n if (!this.coordinator.onLogonRejectedForSequence(AsciiSession.MaxLogonRetries)) {\n this.sessionLogger.warning(`max logon retries (${AsciiSession.MaxLogonRetries}) exceeded, giving up. Text='${text}'`)\n this.setState(SessionState.PeerLogonRejected)\n this.stop()\n return\n }\n\n // The encoder's msgSeqNum is already incremented after each message is sent,\n // so we just need to retry the logon. The next logon will use the next sequence number.\n this.sessionLogger.info(`LOGON_SEQ_RETRY: attempt=${this.coordinator.logonRetryCount}/${AsciiSession.MaxLogonRetries}, reason='${text}'`)\n this.sendLogon()\n }\n\n okForLogon (): boolean {\n const state = this.sessionState.state\n if (this.acceptor) {\n return state === SessionState.WaitingForALogon\n }\n return state === SessionState.InitiationLogonSent\n }\n\n protected onSessionMsg (msgType: string, view: MsgView): void {\n const logger = this.sessionLogger\n\n switch (msgType) {\n case MsgType.Logon: {\n // only valid to receive a logon when in LogonSent or WaitingALogon\n // else will drop connection immediately.\n if (this.okForLogon()) {\n this.peerLogon(view)\n } else {\n this.terminate(new Error(`state ${this.stateString()} is illegal for Logon`))\n }\n break\n }\n\n case MsgType.Logout: {\n this.peerLogout(view)\n break\n }\n\n case MsgType.TestRequest: {\n const req: string | null = view.getString(MsgTag.TestReqID)\n if (req) {\n this.sendHeartbeat(req)\n }\n break\n }\n\n case MsgType.Heartbeat: {\n this.sessionState.lastTestRequestAt = null\n this.setState(SessionState.ActiveNormalSession)\n break\n }\n\n case MsgType.ResendRequest: {\n logger.info(`peer sends '${msgType}' resend request.`)\n this.onResendRequest(view)\n break\n }\n\n case MsgType.SequenceReset: {\n const newSeqNo: number = view.getTyped(MsgTag.NewSeqNo) as number\n const gapFillSeq: number = view.getTyped(MsgTag.MsgSeqNum) as number\n logger.info(`peer sends '${msgType}' sequence reset. newSeqNo = ${newSeqNo}`)\n // expect newSeqNo to be the next message's sequence number.\n this.sessionState.lastPeerMsgSeqNum = newSeqNo - 1\n // Notify coordinator to update expected target and clear pending resend requests\n this.coordinator.onGapFillReceived(gapFillSeq, newSeqNo).catch((e: Error) => {\n this.sessionLogger.warning(`coordinator.onGapFillReceived store persist failed: ${e.message}`)\n })\n break\n }\n\n case MsgType.Reject: {\n const refMsgType = view.getString(MsgTag.RefMsgType)\n const text = view.getString(MsgTag.Text)\n const reason = view.getTyped(MsgTag.SessionRejectReason) as number | undefined\n logger.info(`peer rejects RefMsgType='${refMsgType}', reason=${reason}, text='${text}'`)\n\n // Check if this is a logon rejection due to sequence mismatch while we're waiting for logon response.\n // Only retry for ValueIsIncorrect (sequence too low) — structural rejections (RequiredTagMissing etc.)\n // indicate a config problem that retrying won't fix.\n if (refMsgType === MsgType.Logon &&\n this.sessionState.state === SessionState.InitiationLogonSent &&\n reason === SessionRejectReason.ValueIsIncorrect) {\n this.handleLogonRejected(text)\n }\n break\n }\n }\n }\n\n protected onMsg (msgType: string, view: MsgView): void {\n if (this.wildcardTarget && !this.identityBound) {\n this.onMsgBeforeIdentity(msgType, view)\n return\n }\n this.dispatchMsg(msgType, view)\n }\n\n /**\n * Message handling for a wildcard acceptor which has not yet learned who it is\n * talking to. The first message must be a Logon; it carries the peer's\n * SenderCompID, which becomes our TargetCompID and hence our SessionId and store.\n *\n * Binding is asynchronous (the store may have to be read from disk) while message\n * delivery is not: the parser emits every message it finds in a TCP segment in one\n * synchronous burst, and a view is only valid for the duration of its own event -\n * AsciiParser recycles the tag index and buffer immediately afterwards. So each\n * message that arrives mid-bind is cloned and queued, then replayed in order.\n */\n private onMsgBeforeIdentity (msgType: string, view: MsgView): void {\n if (this.bindInProgress) {\n this.sessionLogger.info(`queueing '${msgType}' received while binding session identity`)\n this.pendingRx.push({ msgType, view: view.clone() })\n return\n }\n\n if (msgType !== MsgType.Logon) {\n this.terminate(new Error(`wildcard acceptor expects Logon as the first message, received '${msgType}'`))\n return\n }\n\n const peerCompId = view.getString(MsgTag.SenderCompID)\n if (!peerCompId) {\n this.terminate(new Error('Logon has no SenderCompID - cannot establish session identity'))\n return\n }\n\n this.bindInProgress = true\n const logon = view.clone()\n this.transport?.duplex.readable?.pause()\n\n this.bindIdentity(peerCompId).then(() => {\n this.bindInProgress = false\n this.identityBound = true\n this.dispatchMsg(MsgType.Logon, logon)\n this.drainPendingRx()\n this.transport?.duplex.readable?.resume()\n }).catch((e: Error) => {\n this.bindInProgress = false\n this.pendingRx.length = 0\n this.terminate(new Error(`failed to bind session identity for peer '${peerCompId}': ${e.message}`))\n })\n }\n\n private drainPendingRx (): void {\n while (this.pendingRx.length > 0) {\n const queued = this.pendingRx.shift()\n if (!queued) break\n if (this.sessionState.state === SessionState.Stopped) {\n this.sessionLogger.info(`dropping queued '${queued.msgType}' - session stopped during bind`)\n continue\n }\n this.dispatchMsg(queued.msgType, queued.view)\n }\n }\n\n /**\n * Adopt the peer's comp id as our TargetCompID, then build the identity derived\n * state: SessionId, message store, sequence coordinator, registry claim. This is\n * the wildcard equivalent of the work run() does up front for a statically\n * configured session.\n */\n private async bindIdentity (peerCompId: string): Promise<void> {\n const logger = this.sessionLogger\n logger.info(`wildcard acceptor: binding session identity to peer SenderCompID '${peerCompId}'`)\n\n // the description is this session's own clone (see makeSessionScope), and the\n // session message factory holds the same object, so outbound headers pick the\n // new target up immediately\n asMutable(this.config.description).TargetCompID = peerCompId\n\n // every session on a wildcard listener shared one logger name until now, which\n // makes a multi-client server log impossible to follow\n this.sessionLogger = this.config.logFactory.logger(`${this.me}:${peerCompId}:FixSession`)\n\n this.sessionId = new SessionId(\n this.config.description.BeginString,\n this.config.description.SenderCompId,\n peerCompId\n )\n this.sessionStore = this.storeFactory().create(this.sessionId)\n await this.sessionStore.initialize()\n\n this.coordinator = new SessionSequenceCoordinator(this.sessionStore, this.clock)\n this.coordinator.initializeFromStore()\n\n const transmitter = this.transport?.transmitter as AsciiMsgTransmitter | undefined\n if (transmitter) {\n transmitter.msgSeqNum = this.coordinator.nextSenderSeqNum\n }\n this.sessionState.lastPeerMsgSeqNum = this.coordinator.lastProcessedPeerSeqNum\n\n logger.info(`session identity bound: ${this.sessionId.toString()} ` +\n `nextSender=${this.coordinator.nextSenderSeqNum}, expectedTarget=${this.coordinator.expectedTargetSeqNum}`)\n\n this.claimSessionId()\n }\n\n private dispatchMsg (msgType: string, view: MsgView): void {\n if (!this.checkSeqNo(msgType, view)) {\n this.sessionLogger.info(`message '${msgType}' failed checkSeqNo.`)\n return\n }\n\n if (this.checkMsgIntegrity && !this.checkIntegrity(msgType, view)) {\n this.sessionLogger.info(`message '${msgType}' failed checkIntegrity.`)\n switch (msgType) {\n case MsgType.Logon: {\n this.setState(SessionState.PeerLogonRejected)\n this.startTimer()\n break\n }\n }\n return\n }\n\n switch (msgType) {\n case MsgType.Logon:\n case MsgType.Logout:\n case MsgType.TestRequest:\n case MsgType.Reject:\n case MsgType.SequenceReset:\n case MsgType.Heartbeat:\n case MsgType.ResendRequest: {\n this.onSessionMsg(msgType, view)\n break\n }\n\n default: {\n this.checkForwardMsg(msgType, view)\n break\n }\n }\n }\n\n private startTimer (interval: number = 200): void {\n const logger = this.sessionLogger\n logger.info(`start heartbeat timer. interval = ${interval}`)\n this.timer = setInterval(() => {\n this.tick()\n }, interval)\n }\n\n private peerLogon (view: MsgView): void {\n const logger = this.sessionLogger\n const [heartBtInt, peerCompId, userName, password] = view.getTypedTags([MsgTag.HeartBtInt, MsgTag.SenderCompID, MsgTag.Username, MsgTag.Password])\n const resetSeqNumFlag = view.getTyped(MsgTag.ResetSeqNumFlag) as boolean | undefined\n logger.info(`peerLogon Username = ${userName}, heartBtInt = ${heartBtInt}, peerCompId = ${peerCompId}, resetSeqNumFlag = ${resetSeqNumFlag}`)\n\n // Handle ResetSeqNumFlag from peer's logon\n if (resetSeqNumFlag === true) {\n const peerSeqNum = (view.getTyped(MsgTag.MsgSeqNum) as number) ?? 1\n const weAlsoReset = this.config.description.ResetSeqNumFlag\n logger.info(`peer sent ResetSeqNumFlag=Y with seqNum=${peerSeqNum}, weAlsoReset=${weAlsoReset}`)\n\n const transmitter = this.transport?.transmitter as AsciiMsgTransmitter | undefined\n const savedEncoderSeqNum = weAlsoReset && transmitter ? transmitter.msgSeqNum : null\n\n // Fire-and-forget the async coordinator call (store updates resolve on next microtask)\n // but compute the expected values synchronously since we know the reset outcome\n this.coordinator.handlePeerReset(peerSeqNum, weAlsoReset).catch((e: Error) => {\n this.sessionLogger.warning(`coordinator.handlePeerReset store persist failed: ${e.message}`)\n })\n if (transmitter) {\n transmitter.msgSeqNum = savedEncoderSeqNum ?? 1\n }\n this.sessionState.lastPeerMsgSeqNum = peerSeqNum\n\n // Recreate resender with empty store\n if (this.store) {\n this.store.clear().catch((e: Error) => {\n this.sessionLogger.warning(`store.clear failed: ${e.message}`)\n })\n this.resender = new FixMsgAsciiStoreResend(this.store, this.config)\n }\n logger.info(`reset complete: encoderSeqNum=${transmitter?.msgSeqNum}, lastPeerMsgSeqNum=${peerSeqNum}`)\n }\n\n const state = this.sessionState\n state.peerHeartBeatSecs = view.getTyped(MsgTag.HeartBtInt) as number\n state.peerCompId = view.getTyped(MsgTag.SenderCompID) as string\n const res = this.onLogon(view, userName as string, password as string)\n // currently not using this.\n logger.info(`peerLogon onLogon returns ${res}`)\n if (this.acceptor) {\n this.setState(SessionState.InitiationLogonResponse)\n logger.info('acceptor responds to logon request')\n\n // If WE (acceptor) are sending ResetSeqNumFlag=Y but peer didn't request it,\n // reset our sequences before sending our logon response.\n // This handles the broker-reset pattern where client sends N, we respond with Y.\n const weReset = this.config.description.ResetSeqNumFlag\n if (weReset && resetSeqNumFlag !== true) {\n logger.info('acceptor sending ResetSeqNumFlag=Y (peer sent N), resetting sequences')\n // Fire-and-forget async coordinator call, set values synchronously\n this.coordinator.resetAsAcceptor().catch((e: Error) => {\n this.sessionLogger.warning(`coordinator.resetAsAcceptor store persist failed: ${e.message}`)\n })\n const transmitter = this.transport?.transmitter as AsciiMsgTransmitter | undefined\n if (transmitter) {\n transmitter.msgSeqNum = 1\n }\n this.sessionState.lastPeerMsgSeqNum = 0\n if (this.store) {\n this.store.clear().catch((e: Error) => {\n this.sessionLogger.warning(`store.clear failed: ${e.message}`)\n })\n this.resender = new FixMsgAsciiStoreResend(this.store, this.config)\n }\n }\n\n this.sendLogon() // if res send response else reject, terminate\n } else { // as an initiator the acceptor has responded\n logger.info('initiator receives logon response')\n this.setState(SessionState.InitiationLogonReceived)\n }\n // Reset logon retry counter on successful logon\n this.coordinator.resetLogonRetryCount()\n\n if (this.heartbeat) {\n this.startTimer()\n }\n logger.info('system ready, inform app')\n this.onReady(view)\n }\n\n private sendTestRequest (): void {\n const factory = this.config.factory\n this.setState(SessionState.AwaitingProcessingResponseToTestRequest)\n const tr = factory?.testRequest()\n if (tr) {\n this.send(MsgType.TestRequest, tr)\n }\n }\n\n private sendHeartbeat (testReqId: string): void {\n const factory = this.config.factory\n const hb = factory?.heartbeat(testReqId)\n if (hb) {\n this.send(MsgType.Heartbeat, hb)\n }\n }\n\n private tick (): void {\n if (!this.transport) return\n const sessionState = this.sessionState\n const action: TickAction = sessionState.calcAction(new Date())\n const application: IMsgApplication | null = this.transport.config.description.application ?? null\n const logger = this.sessionLogger\n // Clean up timed-out resend requests\n this.coordinator.tick()\n\n switch (action) {\n case TickAction.Nothing: {\n // all is well\n break\n }\n\n case TickAction.TestRequest: {\n logger.debug(`send test req. state = ${sessionState.toString()}`)\n this.sendTestRequest()\n break\n }\n\n case TickAction.Heartbeat: {\n logger.debug(`send heartbeat. state = ${sessionState.toString()}`)\n this.sendHeartbeat(sessionState.now.toUTCString())\n break\n }\n\n case TickAction.TerminateOnError: {\n if (this.coordinator.incrementTimeoutRecovery(AsciiSession.MaxTimeoutRecoveryAttempts)) {\n // Try to recover — reset timeout state to give session a fresh window.\n // This helps survive sleep/wake scenarios where TCP connection may still be alive.\n logger.info(`timeout recovery attempt ${this.coordinator.timeoutRecoveryAttempts}, resetting timeout state`)\n sessionState.lastTestRequestAt = null\n sessionState.lastReceivedAt = new Date()\n this.setState(SessionState.ActiveNormalSession)\n } else {\n logger.info(sessionState.toString())\n this.terminate(new Error(`${application?.name}: peer not responding`))\n }\n break\n }\n\n case TickAction.Stop: {\n logger.info(sessionState.toString())\n logger.info('stopping')\n this.stop()\n break\n }\n\n default:\n throw new Error('unexpected action')\n }\n }\n}\n"]}
1
+ {"version":3,"file":"ascii-session.js","sourceRoot":"","sources":["../../../src/transport/ascii/ascii-session.ts"],"names":[],"mappings":"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","sourcesContent":["import { MsgView } from '../../buffer'\nimport { MsgTag, MsgType, SessionRejectReason } from '../../types'\nimport { IJsFixConfig } from '../../config'\nimport { FixSession } from '../session/fix-session'\nimport {\n FixMsgAsciiStoreResend, FixMsgMemoryStore, FixMsgStoreRecord,\n IFixMsgStore, IFixMsgStoreRecord,\n IFixSessionStore, IFixSessionStoreFactory,\n MemorySessionStore, MemorySessionStoreFactory, FileSessionStoreFactory, SessionId\n} from '../../store'\nimport { asMutable } from '../session/clone-session-description'\nimport { SessionState } from '../tcp'\nimport { TickAction } from '../tick-action'\nimport { IMsgApplication } from '../msg-application'\nimport { SegmentType } from '../../buffer/segment/segment-type'\nimport { SessionSequenceCoordinator } from '../session/session-sequence-coordinator'\nimport { DefaultFixClock } from '../session/fix-clock'\nimport { ResendActionType } from '../session/resend-request-manager'\nimport { AsciiMsgTransmitter } from './ascii-msg-transmitter'\nimport { MsgTransport } from '../factory'\nimport { ILooseObject } from '../../collections/collection'\n\nexport abstract class AsciiSession extends FixSession {\n /**\n * TargetCompID value which tells an acceptor to take its target from whichever\n * counterparty logs on, rather than from static configuration.\n */\n public static readonly WildcardCompId = '*'\n public heartbeat: boolean = true\n protected store: IFixMsgStore | null = null\n protected resender: FixMsgAsciiStoreResend\n protected coordinator: SessionSequenceCoordinator\n protected sessionStore: IFixSessionStore\n protected sessionId: SessionId\n private registered: boolean = false\n /** acceptor configured with TargetCompID '*' - identity comes from the peer Logon */\n protected readonly wildcardTarget: boolean\n private identityBound: boolean\n private bindInProgress: boolean = false\n private logonVerdictPending: boolean = false\n private readonly pendingRx: Array<{ msgType: string, view: MsgView }> = []\n private readonly clock: DefaultFixClock = new DefaultFixClock()\n\n protected constructor (public readonly config: IJsFixConfig) {\n super(config)\n this.requestLogoutType = this.respondLogoutType = MsgType.Logout\n this.requestLogonType = MsgType.Logon\n this.store = new FixMsgMemoryStore(this.config.description.SenderCompId, this.config)\n this.resender = new FixMsgAsciiStoreResend(this.store, this.config)\n\n // A wildcard TargetCompID lets one acceptor serve counterparties it was not\n // statically configured for - the peer's SenderCompID becomes our target, and\n // therefore our SessionId and store, once the Logon arrives. An initiator has\n // to know who it is calling, so '*' is meaningless there.\n this.wildcardTarget = config.description.TargetCompID === AsciiSession.WildcardCompId\n if (this.wildcardTarget && this.initiator) {\n throw new Error(`TargetCompID '${AsciiSession.WildcardCompId}' is only valid for acceptors, not initiators`)\n }\n this.identityBound = !this.wildcardTarget\n\n this.sessionId = new SessionId(\n config.description.BeginString,\n config.description.SenderCompId,\n config.description.TargetCompID\n )\n // Until the peer identifies itself there is nothing worth persisting, so a\n // wildcard session starts on a throwaway in-memory store. The real store -\n // keyed on the peer's comp id - is created by bindIdentity.\n this.sessionStore = this.wildcardTarget\n ? new MemorySessionStore(this.sessionId)\n : this.storeFactory().create(this.sessionId)\n\n this.coordinator = new SessionSequenceCoordinator(this.sessionStore, this.clock)\n const lastReceivedSeqNum = config.description.LastReceivedSeqNum ?? 0\n this.coordinator.initializeFromConfig(undefined, lastReceivedSeqNum + 1)\n }\n\n private storeFactory (): IFixSessionStoreFactory {\n // Priority: programmatic config > JSON store config > default in-memory\n return this.config.sessionStoreFactory ?? AsciiSession.createStoreFactory(this.config.description.store)\n }\n\n /**\n * Initialize the session store (reads persisted sequences from file if using FileSessionStore),\n * sync the coordinator and transmitter from the store, then start the session.\n *\n * The transport's readable stream is paused during async store initialization to prevent\n * the AsciiParser (which starts reading immediately in its constructor) from consuming\n * and emitting messages before subscribe() hooks up the message handler.\n */\n public async run (transport: MsgTransport): Promise<number> {\n // Pause the readable stream to prevent data loss during async init.\n // The AsciiParser starts reading from the socket in its constructor,\n // but FixSession.subscribe() hasn't been called yet. Without pausing,\n // the client's Logon can arrive and be parsed into the void.\n transport.duplex.readable?.pause()\n\n if (this.wildcardTarget && !this.identityBound) {\n // Nothing to recover yet - the SessionId is not known until the peer logs on,\n // so store initialisation, sequence sync and registry claim all happen in\n // bindIdentity. Resume and wait for the Logon.\n this.sessionLogger.info('wildcard acceptor: awaiting peer Logon to establish session identity')\n transport.duplex.readable?.resume()\n return await super.run(transport)\n }\n\n // Initialize store — reads persisted .seqnums file if using FileSessionStore.\n // For MemorySessionStore this is a no-op.\n await this.sessionStore.initialize()\n\n // Coordinator becomes the source of truth for sequences\n this.coordinator.initializeFromStore()\n\n // Sync encoder's outgoing sequence from the store\n const transmitter = transport.transmitter as AsciiMsgTransmitter\n transmitter.msgSeqNum = this.coordinator.nextSenderSeqNum\n\n // Sync session state's last received sequence from the store\n this.sessionState.lastPeerMsgSeqNum = this.coordinator.lastProcessedPeerSeqNum\n\n this.sessionLogger.info(`store initialized: nextSender=${this.coordinator.nextSenderSeqNum}, expectedTarget=${this.coordinator.expectedTargetSeqNum}`)\n\n // Claim this SessionId. A counterparty which reconnected before its previous\n // socket was detected as dead would otherwise leave two live sessions writing\n // to one store - see issue #153.\n this.claimSessionId()\n\n // Resume the stream — super.run() will call subscribe() to hook up the message handler,\n // then the buffered data (including the client's Logon) will be delivered.\n transport.duplex.readable?.resume()\n\n return await super.run(transport)\n }\n\n private checkSeqNo (msgType: string, view: MsgView): boolean {\n switch (msgType) {\n case MsgType.SequenceReset: {\n return true\n }\n\n case MsgType.Logon: {\n // If peer sends ResetSeqNumFlag=Y, accept any sequence number.\n // PeerLogon handles the full sequence reset.\n if (view.getTyped(MsgTag.ResetSeqNumFlag) === true) {\n this.sessionLogger.info('logon with ResetSeqNumFlag=Y, accepting regardless of sequence')\n const seqNo = view.getTyped(MsgTag.MsgSeqNum) as number\n this.sessionState.lastPeerMsgSeqNum = seqNo\n this.coordinator.onMessageReceived(seqNo, false).catch((e: Error) => {\n this.sessionLogger.warning(`coordinator.onMessageReceived store persist failed: ${e.message}`)\n })\n return true\n }\n }\n // falls through\n\n default: {\n const state = this.sessionState\n const lastSeq: number = state.lastPeerMsgSeqNum\n const seqNo: number = view.getTyped(MsgTag.MsgSeqNum) as number\n let ret: boolean = false\n const seqDelta: number = seqNo - lastSeq\n if (seqDelta <= 0) {\n // Check if this is a PossDupFlag=Y message (resend replay) before rejecting.\n // PossDupFlag messages have old sequence numbers and bypass normal checks.\n const possDupFlag = view.getTyped(MsgTag.PossDupFlag) as boolean | undefined\n if (possDupFlag === true) {\n this.sessionLogger.debug(`message '${msgType}' has PossDupFlag=Y, bypassing sequence check`)\n this.coordinator.onMessageReceived(seqNo, true).catch((e: Error) => {\n this.sessionLogger.warning(`coordinator.onMessageReceived store persist failed: ${e.message}`)\n })\n return true\n }\n // Check if this is a delayed message that fills a pending gap range.\n const pendingRequests = this.coordinator.pendingResendRequests\n const inPendingGapRange = pendingRequests.some(p => seqNo >= p.begin && seqNo <= p.end)\n if (inPendingGapRange) {\n this.sessionLogger.info(`accepting delayed message seq ${seqNo} (in pending gap range)`)\n this.coordinator.onMessageReceived(seqNo, false).catch((e: Error) => {\n this.sessionLogger.warning(`coordinator.onMessageReceived store persist failed: ${e.message}`)\n })\n return true\n }\n // serious problem ... drop immediately\n this.sessionLogger.warning(`terminate as seqDelta (${seqDelta}) < 0 lastSeq = ${lastSeq} seqNo = ${seqNo}`)\n this.stop()\n } else if (seqDelta > 1) {\n // resend request required as have missed messages.\n const expectedSeq = lastSeq + 1\n\n // We process a Logon beforehand to confirm the connection even we out of sync\n if (msgType === MsgType.Logon) {\n this.peerLogon(view)\n }\n // If the out of sync message is a resend request itself, then we handle it first in order\n // to avoid triggering an endless loop of both sides sending resend requests in response to resend requests.\n if (msgType === MsgType.ResendRequest) {\n this.onResendRequest(view)\n }\n\n // Use coordinator to determine what action to take for the gap\n const action = this.coordinator.onGapDetected(expectedSeq, seqNo)\n this.sessionLogger.info(`gap action: ${action}`)\n\n switch (action.type) {\n case ResendActionType.SendResendRequest: {\n if (action.begin != null && action.end != null) {\n this.sendResendRequest(lastSeq, seqNo)\n this.coordinator.recordResendRequestSent(action.begin, action.end)\n }\n break\n }\n case ResendActionType.Wait: {\n this.sessionLogger.info(`waiting for existing resend request: ${action.reason}`)\n break\n }\n case ResendActionType.SendGapFill: {\n this.sessionLogger.warning(`gap recovery abandoned (storm protection): ${action.reason}`)\n break\n }\n }\n\n // Update sequence state regardless — the gap-triggering message is valid.\n state.lastPeerMsgSeqNum = seqNo\n this.coordinator.onMessageReceived(seqNo, false).catch((e: Error) => {\n this.sessionLogger.warning(`coordinator.onMessageReceived store persist failed: ${e.message}`)\n })\n\n // Logon and ResendRequest were already fully handled above (peerLogon / onResendRequest).\n // Don't return true for them — they must not be dispatched to onSessionMsg again.\n // Application messages (and everything else) should be forwarded normally.\n if (msgType !== MsgType.Logon && msgType !== MsgType.ResendRequest) {\n ret = true\n }\n } else {\n ret = true\n state.lastPeerMsgSeqNum = seqNo\n this.coordinator.onMessageReceived(seqNo, false).catch((e: Error) => {\n this.sessionLogger.warning(`coordinator.onMessageReceived store persist failed: ${e.message}`)\n })\n }\n\n // Reset timeout recovery on successful message receipt\n if (ret) {\n this.coordinator.resetTimeoutRecovery()\n }\n return ret\n }\n }\n }\n\n protected checkForwardMsg (msgType: string, view: MsgView): void {\n const okToForward = this.validStateApplicationMsg()\n if (okToForward) {\n this.sessionLogger.info(`ascii forwarding msgType = '${msgType}' to application`)\n this.setState(SessionState.ActiveNormalSession)\n this.onApplicationMsg(msgType, view)\n } else {\n this.terminate(new Error(`msgType ${msgType} received in state ${this.stateString()}`))\n }\n }\n\n private sendReject (msgType: string, seqNo: number, msg: string, reason: number): void {\n const factory = this.config.factory\n const reject = factory?.reject(msgType, seqNo, msg, reason)\n if (reject) {\n this.sessionLogger.warning(`rejecting with ${JSON.stringify(reject)}`)\n this.send(MsgType.Reject, reject)\n }\n }\n\n protected sendResendRequest (lastSeq: number, receivedSeq: number): void {\n const resend = this.config.factory?.resendRequest(lastSeq + 1, 0)\n if (resend) {\n this.sessionLogger.warning(`received seq ${receivedSeq}, but last known seq is ${lastSeq}. Sending resend request for all messages > ${lastSeq}`)\n this.send(MsgType.ResendRequest, resend)\n }\n }\n\n private checkIntegrity (msgType: string, view: MsgView): boolean {\n const state = this.sessionState\n const seqNum = view.getTyped(MsgTag.MsgSeqNum) as number\n\n const received: number = parseInt(view.getString(MsgTag.CheckSum) ?? '', 10)\n const computed = view.checksum()\n if (received !== computed) {\n const msg: string = `msgType ${msgType} checksum failed. received = ${received} computed = ${computed}`\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.ValueIsIncorrect)\n return false\n }\n\n if (view.segment.type === SegmentType.Unknown) {\n const msg: string = `msgType ${msgType} unknown`\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.InvalidMsgType)\n return false\n }\n\n const invalid = view.invalid()\n if (invalid.length > 0) {\n const msg: string = `msgType ${msgType} invalid tag${invalid.length > 1 ? 's' : ''} ${invalid.join(', ')}`\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.InvalidTagNumber)\n return false\n }\n\n const undefinedMsg: string | null = view.undefinedForMsg()\n if (undefinedMsg) {\n const msg: string = `msgType ${msgType} ${undefinedMsg}`\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.TagNotDefinedForThisMessageType)\n return false\n }\n\n const missingRequired = view.missing()\n if (missingRequired.length > 0) {\n const msg: string = `msgType ${msgType} missing required tag${missingRequired.length > 1 ? 's' : ''} ${missingRequired.join(', ')}`\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.RequiredTagMissing)\n return false\n }\n\n switch (state.state) {\n case SessionState.InitiationLogonReceived:\n case SessionState.InitiationLogonResponse: {\n const targetCompId = view.getString(MsgTag.TargetCompID)\n if (targetCompId !== state.compId) {\n const msg: string = `msgType ${msgType} unexpected TargetCompID ${targetCompId} expecting ${state.compId})`\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.CompIDProblem)\n return false\n }\n\n const peerCompId = view.getString(MsgTag.SenderCompID)\n if (peerCompId !== state.peerCompId) {\n const msg: string = `msgType ${msgType} unexpected SenderCompID ${peerCompId} expecting ${state.compId}`\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.CompIDProblem)\n return false\n }\n }\n break\n\n default: {\n break\n }\n }\n\n return true\n }\n\n /**\n * Override to resend stored messages following a sequence reset.\n * @protected\n */\n protected onResendRequest (view: MsgView): void {\n // if no records are in store then send a gap fill for entire sequence\n this.setState(SessionState.HandleResendRequest)\n const [beginSeqNo, requestedEndSeqNo] = view.getTypedTags([MsgTag.BeginSeqNo, MsgTag.EndSeqNo])\n const endSeqNo = requestedEndSeqNo === 0\n ? this.sessionState.lastSentSeqNum()\n : requestedEndSeqNo\n\n this.sessionLogger.info(`onResendRequest getResendRequest beginSeqNo = ${beginSeqNo}, endSeqNo = ${endSeqNo}`)\n this.resender.getResendRequest(beginSeqNo as number, endSeqNo as number).then((records: IFixMsgStoreRecord[]) => {\n const validRecords = records.filter(rec => rec.obj !== null)\n this.sessionLogger.info(`sending ${validRecords.length}`)\n validRecords.forEach(rec => {\n if (rec.obj) {\n this.send(rec.msgType, rec.obj)\n }\n })\n this.setState(SessionState.ActiveNormalSession)\n }).catch((e: Error) => {\n this.sessionLogger.error(e)\n })\n }\n\n protected override onPrepareForReconnect (): void {\n this.coordinator.prepareForReconnect()\n this.sessionLogger.info('coordinator reset transient state for reconnect')\n }\n\n /**\n * Take ownership of this SessionId in the registry, stopping whatever session\n * held it before. Idempotent - a session reused across reconnects (the\n * RecoveringTcpInitiator pattern) simply re-registers itself.\n */\n private claimSessionId (): void {\n const registry = this.config.sessionRegistry\n if (!registry) return\n const stoppedOld = registry.register(this.sessionId, this)\n if (stoppedOld) {\n this.sessionLogger.info(`session registry stopped previous session for ${this.sessionId.toString()}`)\n }\n this.registered = true\n }\n\n protected override onSessionStopping (): void {\n super.onSessionStopping()\n const registry = this.config.sessionRegistry\n if (!registry || !this.registered) return\n this.registered = false\n this.sessionLogger.info(`session stopping - unregistering from registry: ${this.sessionId.toString()}`)\n registry.unregister(this.sessionId, this)\n }\n\n protected override async onPreLogon (): Promise<void> {\n if (!this.config.description.ResetSeqNumFlag) return\n\n this.sessionLogger.info('initiator has ResetSeqNumFlag=Y, resetting sequences before logon')\n await this.coordinator.resetSession('initiator ResetSeqNumFlag=Y')\n\n const transmitter = this.transport?.transmitter as AsciiMsgTransmitter | undefined\n if (transmitter) {\n transmitter.msgSeqNum = this.coordinator.nextSenderSeqNum\n }\n this.sessionState.lastPeerMsgSeqNum = this.coordinator.lastProcessedPeerSeqNum\n\n if (this.store) {\n this.store.clear().catch((e: Error) => {\n this.sessionLogger.warning(`store.clear failed: ${e.message}`)\n })\n this.resender = new FixMsgAsciiStoreResend(this.store, this.config)\n }\n\n this.sessionLogger.info(`pre-logon reset complete: encoderSeqNum=${transmitter?.msgSeqNum}`)\n }\n\n protected override txOnEncoded (msgType: string, data: string, hdr: ILooseObject): void {\n super.txOnEncoded(msgType, data, hdr)\n // Store the encoded message in the session store for recovery/resend\n const seqNum = hdr?.MsgSeqNum as number | undefined\n if (seqNum != null) {\n const record = new FixMsgStoreRecord(msgType, new Date(), seqNum, undefined, data)\n this.sessionStore.put(record).catch((e: Error) => {\n // Never block sends on store errors\n this.sessionLogger.warning(`failed to store message seq=${seqNum}: ${e.message}`)\n })\n // Update store's sender sequence number (next outgoing seq = seqNum + 1)\n this.sessionStore.setSenderSeqNum(seqNum + 1).catch((e: Error) => {\n this.sessionLogger.warning(`failed to update sender seq: ${e.message}`)\n })\n }\n }\n\n private static readonly MaxLogonRetries = 100\n private static readonly MaxTimeoutRecoveryAttempts = 0\n\n private static createStoreFactory (storeConfig?: { type: string, directory?: string }): IFixSessionStoreFactory {\n if (!storeConfig) return new MemorySessionStoreFactory()\n switch (storeConfig.type?.toLowerCase()) {\n case 'file':\n return new FileSessionStoreFactory(storeConfig.directory ?? 'store')\n default:\n return new MemorySessionStoreFactory()\n }\n }\n\n private handleLogonRejected (text: string | null): void {\n if (!this.coordinator.onLogonRejectedForSequence(AsciiSession.MaxLogonRetries)) {\n this.sessionLogger.warning(`max logon retries (${AsciiSession.MaxLogonRetries}) exceeded, giving up. Text='${text}'`)\n this.setState(SessionState.PeerLogonRejected)\n this.stop()\n return\n }\n\n // The encoder's msgSeqNum is already incremented after each message is sent,\n // so we just need to retry the logon. The next logon will use the next sequence number.\n this.sessionLogger.info(`LOGON_SEQ_RETRY: attempt=${this.coordinator.logonRetryCount}/${AsciiSession.MaxLogonRetries}, reason='${text}'`)\n this.sendLogon()\n }\n\n okForLogon (): boolean {\n const state = this.sessionState.state\n if (this.acceptor) {\n return state === SessionState.WaitingForALogon\n }\n return state === SessionState.InitiationLogonSent\n }\n\n protected onSessionMsg (msgType: string, view: MsgView): void {\n const logger = this.sessionLogger\n\n switch (msgType) {\n case MsgType.Logon: {\n // only valid to receive a logon when in LogonSent or WaitingALogon\n // else will drop connection immediately.\n if (this.okForLogon()) {\n this.peerLogon(view)\n } else {\n this.terminate(new Error(`state ${this.stateString()} is illegal for Logon`))\n }\n break\n }\n\n case MsgType.Logout: {\n this.peerLogout(view)\n break\n }\n\n case MsgType.TestRequest: {\n const req: string | null = view.getString(MsgTag.TestReqID)\n if (req) {\n this.sendHeartbeat(req)\n }\n break\n }\n\n case MsgType.Heartbeat: {\n this.sessionState.lastTestRequestAt = null\n this.setState(SessionState.ActiveNormalSession)\n break\n }\n\n case MsgType.ResendRequest: {\n logger.info(`peer sends '${msgType}' resend request.`)\n this.onResendRequest(view)\n break\n }\n\n case MsgType.SequenceReset: {\n const newSeqNo: number = view.getTyped(MsgTag.NewSeqNo) as number\n const gapFillSeq: number = view.getTyped(MsgTag.MsgSeqNum) as number\n logger.info(`peer sends '${msgType}' sequence reset. newSeqNo = ${newSeqNo}`)\n // expect newSeqNo to be the next message's sequence number.\n this.sessionState.lastPeerMsgSeqNum = newSeqNo - 1\n // Notify coordinator to update expected target and clear pending resend requests\n this.coordinator.onGapFillReceived(gapFillSeq, newSeqNo).catch((e: Error) => {\n this.sessionLogger.warning(`coordinator.onGapFillReceived store persist failed: ${e.message}`)\n })\n break\n }\n\n case MsgType.Reject: {\n const refMsgType = view.getString(MsgTag.RefMsgType)\n const text = view.getString(MsgTag.Text)\n const reason = view.getTyped(MsgTag.SessionRejectReason) as number | undefined\n logger.info(`peer rejects RefMsgType='${refMsgType}', reason=${reason}, text='${text}'`)\n\n // Check if this is a logon rejection due to sequence mismatch while we're waiting for logon response.\n // Only retry for ValueIsIncorrect (sequence too low) — structural rejections (RequiredTagMissing etc.)\n // indicate a config problem that retrying won't fix.\n if (refMsgType === MsgType.Logon &&\n this.sessionState.state === SessionState.InitiationLogonSent &&\n reason === SessionRejectReason.ValueIsIncorrect) {\n this.handleLogonRejected(text)\n }\n break\n }\n }\n }\n\n protected onMsg (msgType: string, view: MsgView): void {\n if (this.wildcardTarget && !this.identityBound) {\n this.onMsgBeforeIdentity(msgType, view)\n return\n }\n if (this.logonVerdictPending) {\n // the application is still deciding whether to accept this peer - hold anything\n // it sends in the meantime rather than acting on it (see awaitLogonVerdict)\n this.sessionLogger.info(`queueing '${msgType}' received while awaiting logon verdict`)\n this.pendingRx.push({ msgType, view: view.clone() })\n return\n }\n this.dispatchMsg(msgType, view)\n }\n\n /**\n * Message handling for a wildcard acceptor which has not yet learned who it is\n * talking to. The first message must be a Logon; it carries the peer's\n * SenderCompID, which becomes our TargetCompID and hence our SessionId and store.\n *\n * Binding is asynchronous (the store may have to be read from disk) while message\n * delivery is not: the parser emits every message it finds in a TCP segment in one\n * synchronous burst, and a view is only valid for the duration of its own event -\n * AsciiParser recycles the tag index and buffer immediately afterwards. So each\n * message that arrives mid-bind is cloned and queued, then replayed in order.\n */\n private onMsgBeforeIdentity (msgType: string, view: MsgView): void {\n if (this.bindInProgress) {\n this.sessionLogger.info(`queueing '${msgType}' received while binding session identity`)\n this.pendingRx.push({ msgType, view: view.clone() })\n return\n }\n\n if (msgType !== MsgType.Logon) {\n this.terminate(new Error(`wildcard acceptor expects Logon as the first message, received '${msgType}'`))\n return\n }\n\n const peerCompId = view.getString(MsgTag.SenderCompID)\n if (!peerCompId) {\n this.terminate(new Error('Logon has no SenderCompID - cannot establish session identity'))\n return\n }\n\n this.bindInProgress = true\n const logon = view.clone()\n this.transport?.duplex.readable?.pause()\n\n this.bindIdentity(peerCompId).then(() => {\n this.bindInProgress = false\n this.identityBound = true\n // dispatching the logon can itself open a second gate - an application whose\n // onLogon returns a promise is now deciding - so let resumeRx work out whether\n // it is actually safe to let the socket run again\n this.dispatchMsg(MsgType.Logon, logon)\n this.resumeRx()\n }).catch((e: Error) => {\n this.bindInProgress = false\n this.pendingRx.length = 0\n this.terminate(new Error(`failed to bind session identity for peer '${peerCompId}': ${e.message}`))\n })\n }\n\n /**\n * True while an asynchronous step in the logon handshake is still running and no\n * received message may be acted on: either the identity bind of a wildcard acceptor\n * or an application still deciding the logon verdict.\n */\n private rxGated (): boolean {\n return this.bindInProgress || this.logonVerdictPending\n }\n\n /**\n * Let the socket run again now a gate has opened - but only if no other gate is\n * still shut. Draining can re-gate (a replayed message could start another async\n * step) so the check is repeated after the queue is played out; whichever gate\n * closes last is the one that resumes.\n */\n private resumeRx (): void {\n if (this.rxGated()) return\n this.drainPendingRx()\n if (this.rxGated()) return\n this.transport?.duplex.readable?.resume()\n }\n\n private drainPendingRx (): void {\n while (this.pendingRx.length > 0) {\n if (this.rxGated()) {\n this.sessionLogger.info('suspending replay - logon handshake gated again')\n return\n }\n const queued = this.pendingRx.shift()\n if (!queued) break\n if (this.sessionState.state === SessionState.Stopped) {\n this.sessionLogger.info(`dropping queued '${queued.msgType}' - session stopped during bind`)\n continue\n }\n this.dispatchMsg(queued.msgType, queued.view)\n }\n }\n\n /**\n * Adopt the peer's comp id as our TargetCompID, then build the identity derived\n * state: SessionId, message store, sequence coordinator, registry claim. This is\n * the wildcard equivalent of the work run() does up front for a statically\n * configured session.\n */\n private async bindIdentity (peerCompId: string): Promise<void> {\n const logger = this.sessionLogger\n logger.info(`wildcard acceptor: binding session identity to peer SenderCompID '${peerCompId}'`)\n\n // the description is this session's own clone (see makeSessionScope), and the\n // session message factory holds the same object, so outbound headers pick the\n // new target up immediately\n asMutable(this.config.description).TargetCompID = peerCompId\n\n // every session on a wildcard listener shared one logger name until now, which\n // makes a multi-client server log impossible to follow\n this.sessionLogger = this.config.logFactory.logger(`${this.me}:${peerCompId}:FixSession`)\n\n this.sessionId = new SessionId(\n this.config.description.BeginString,\n this.config.description.SenderCompId,\n peerCompId\n )\n this.sessionStore = this.storeFactory().create(this.sessionId)\n await this.sessionStore.initialize()\n\n this.coordinator = new SessionSequenceCoordinator(this.sessionStore, this.clock)\n this.coordinator.initializeFromStore()\n\n const transmitter = this.transport?.transmitter as AsciiMsgTransmitter | undefined\n if (transmitter) {\n transmitter.msgSeqNum = this.coordinator.nextSenderSeqNum\n }\n this.sessionState.lastPeerMsgSeqNum = this.coordinator.lastProcessedPeerSeqNum\n\n logger.info(`session identity bound: ${this.sessionId.toString()} ` +\n `nextSender=${this.coordinator.nextSenderSeqNum}, expectedTarget=${this.coordinator.expectedTargetSeqNum}`)\n\n this.claimSessionId()\n }\n\n private dispatchMsg (msgType: string, view: MsgView): void {\n if (!this.checkSeqNo(msgType, view)) {\n this.sessionLogger.info(`message '${msgType}' failed checkSeqNo.`)\n return\n }\n\n if (this.checkMsgIntegrity && !this.checkIntegrity(msgType, view)) {\n this.sessionLogger.info(`message '${msgType}' failed checkIntegrity.`)\n switch (msgType) {\n case MsgType.Logon: {\n this.setState(SessionState.PeerLogonRejected)\n this.startTimer()\n break\n }\n }\n return\n }\n\n switch (msgType) {\n case MsgType.Logon:\n case MsgType.Logout:\n case MsgType.TestRequest:\n case MsgType.Reject:\n case MsgType.SequenceReset:\n case MsgType.Heartbeat:\n case MsgType.ResendRequest: {\n this.onSessionMsg(msgType, view)\n break\n }\n\n default: {\n this.checkForwardMsg(msgType, view)\n break\n }\n }\n }\n\n private startTimer (interval: number = 200): void {\n const logger = this.sessionLogger\n logger.info(`start heartbeat timer. interval = ${interval}`)\n this.timer = setInterval(() => {\n this.tick()\n }, interval)\n }\n\n private peerLogon (view: MsgView): void {\n const logger = this.sessionLogger\n const [heartBtInt, peerCompId, userName, password] = view.getTypedTags([MsgTag.HeartBtInt, MsgTag.SenderCompID, MsgTag.Username, MsgTag.Password])\n const resetSeqNumFlag = view.getTyped(MsgTag.ResetSeqNumFlag) as boolean | undefined\n logger.info(`peerLogon Username = ${userName}, heartBtInt = ${heartBtInt}, peerCompId = ${peerCompId}, resetSeqNumFlag = ${resetSeqNumFlag}`)\n\n // Handle ResetSeqNumFlag from peer's logon\n if (resetSeqNumFlag === true) {\n const peerSeqNum = (view.getTyped(MsgTag.MsgSeqNum) as number) ?? 1\n const weAlsoReset = this.config.description.ResetSeqNumFlag\n logger.info(`peer sent ResetSeqNumFlag=Y with seqNum=${peerSeqNum}, weAlsoReset=${weAlsoReset}`)\n\n const transmitter = this.transport?.transmitter as AsciiMsgTransmitter | undefined\n const savedEncoderSeqNum = weAlsoReset && transmitter ? transmitter.msgSeqNum : null\n\n // Fire-and-forget the async coordinator call (store updates resolve on next microtask)\n // but compute the expected values synchronously since we know the reset outcome\n this.coordinator.handlePeerReset(peerSeqNum, weAlsoReset).catch((e: Error) => {\n this.sessionLogger.warning(`coordinator.handlePeerReset store persist failed: ${e.message}`)\n })\n if (transmitter) {\n transmitter.msgSeqNum = savedEncoderSeqNum ?? 1\n }\n this.sessionState.lastPeerMsgSeqNum = peerSeqNum\n\n // Recreate resender with empty store\n if (this.store) {\n this.store.clear().catch((e: Error) => {\n this.sessionLogger.warning(`store.clear failed: ${e.message}`)\n })\n this.resender = new FixMsgAsciiStoreResend(this.store, this.config)\n }\n logger.info(`reset complete: encoderSeqNum=${transmitter?.msgSeqNum}, lastPeerMsgSeqNum=${peerSeqNum}`)\n }\n\n const state = this.sessionState\n state.peerHeartBeatSecs = view.getTyped(MsgTag.HeartBtInt) as number\n state.peerCompId = view.getTyped(MsgTag.SenderCompID) as string\n\n const verdict = this.onLogon(view, userName as string, password as string)\n if (typeof verdict === 'boolean') {\n // the common case - finish the handshake in this same event, so an application\n // with a synchronous onLogon sees exactly the timing it always has\n this.completePeerLogon(view, verdict, resetSeqNumFlag)\n return\n }\n this.awaitLogonVerdict(view, verdict, resetSeqNumFlag)\n }\n\n /**\n * onLogon handed back a promise - the application is checking the credentials\n * against something asynchronous. Nothing may be sent or acted on until it\n * answers, so pause the socket and queue whatever the peer says in the meantime.\n *\n * The view has to be cloned: AsciiParser recycles its tag index and buffer as soon\n * as the current event returns, so the original is meaningless by the time the\n * promise settles. Anything already read off it - peerReset here - is carried\n * across as a value rather than read again from the clone.\n */\n private awaitLogonVerdict (view: MsgView, verdict: Promise<boolean>, peerReset: boolean | undefined): void {\n const logger = this.sessionLogger\n logger.info('onLogon returned a promise - awaiting logon verdict')\n this.logonVerdictPending = true\n const logon = view.clone()\n this.transport?.duplex.readable?.pause()\n\n verdict.then((accepted: boolean) => {\n this.logonVerdictPending = false\n if (this.sessionState.state === SessionState.Stopped) {\n logger.info('session stopped while awaiting logon verdict - discarding')\n this.pendingRx.length = 0\n return\n }\n this.completePeerLogon(logon, accepted, peerReset)\n if (!accepted) {\n // completePeerLogon has torn the session down - nothing queued can be acted on\n this.pendingRx.length = 0\n return\n }\n this.resumeRx()\n }).catch((e: Error) => {\n this.logonVerdictPending = false\n this.pendingRx.length = 0\n // a credential check that throws is a refusal, not a reason to let the peer in\n this.rejectLogon(`onLogon failed: ${e.message}`)\n })\n }\n\n /**\n * The application has accepted or refused the peer - finish the handshake either way.\n */\n private completePeerLogon (view: MsgView, accepted: boolean, peerReset: boolean | undefined): void {\n const logger = this.sessionLogger\n logger.info(`peerLogon onLogon returns ${accepted}`)\n if (!accepted) {\n this.rejectLogon('logon rejected by application')\n return\n }\n if (this.acceptor) {\n this.setState(SessionState.InitiationLogonResponse)\n logger.info('acceptor responds to logon request')\n\n // If WE (acceptor) are sending ResetSeqNumFlag=Y but peer didn't request it,\n // reset our sequences before sending our logon response.\n // This handles the broker-reset pattern where client sends N, we respond with Y.\n const weReset = this.config.description.ResetSeqNumFlag\n if (weReset && peerReset !== true) {\n logger.info('acceptor sending ResetSeqNumFlag=Y (peer sent N), resetting sequences')\n // Fire-and-forget async coordinator call, set values synchronously\n this.coordinator.resetAsAcceptor().catch((e: Error) => {\n this.sessionLogger.warning(`coordinator.resetAsAcceptor store persist failed: ${e.message}`)\n })\n const transmitter = this.transport?.transmitter as AsciiMsgTransmitter | undefined\n if (transmitter) {\n transmitter.msgSeqNum = 1\n }\n this.sessionState.lastPeerMsgSeqNum = 0\n if (this.store) {\n this.store.clear().catch((e: Error) => {\n this.sessionLogger.warning(`store.clear failed: ${e.message}`)\n })\n this.resender = new FixMsgAsciiStoreResend(this.store, this.config)\n }\n }\n\n this.sendLogon()\n } else { // as an initiator the acceptor has responded\n logger.info('initiator receives logon response')\n this.setState(SessionState.InitiationLogonReceived)\n }\n // Reset logon retry counter on successful logon\n this.coordinator.resetLogonRetryCount()\n\n if (this.heartbeat) {\n this.startTimer()\n }\n logger.info('system ready, inform app')\n this.onReady(view)\n }\n\n /**\n * The application refused this peer. FIX expects the refusing side to say why and\n * then hang up rather than simply going quiet, so send a Logout carrying the reason\n * before dropping the transport - the order matters, send() discards anything\n * offered once the session has stopped.\n *\n * onReady is never reached and no heartbeat timer starts; the application learns the\n * outcome through onStopped(error).\n */\n private rejectLogon (reason: string): void {\n this.sessionLogger.warning(`refusing peer logon: ${reason}`)\n this.sendLogout(reason)\n this.terminate(new Error(reason))\n }\n\n private sendTestRequest (): void {\n const factory = this.config.factory\n this.setState(SessionState.AwaitingProcessingResponseToTestRequest)\n const tr = factory?.testRequest()\n if (tr) {\n this.send(MsgType.TestRequest, tr)\n }\n }\n\n private sendHeartbeat (testReqId: string): void {\n const factory = this.config.factory\n const hb = factory?.heartbeat(testReqId)\n if (hb) {\n this.send(MsgType.Heartbeat, hb)\n }\n }\n\n private tick (): void {\n if (!this.transport) return\n const sessionState = this.sessionState\n const action: TickAction = sessionState.calcAction(new Date())\n const application: IMsgApplication | null = this.transport.config.description.application ?? null\n const logger = this.sessionLogger\n // Clean up timed-out resend requests\n this.coordinator.tick()\n\n switch (action) {\n case TickAction.Nothing: {\n // all is well\n break\n }\n\n case TickAction.TestRequest: {\n logger.debug(`send test req. state = ${sessionState.toString()}`)\n this.sendTestRequest()\n break\n }\n\n case TickAction.Heartbeat: {\n logger.debug(`send heartbeat. state = ${sessionState.toString()}`)\n this.sendHeartbeat(sessionState.now.toUTCString())\n break\n }\n\n case TickAction.TerminateOnError: {\n if (this.coordinator.incrementTimeoutRecovery(AsciiSession.MaxTimeoutRecoveryAttempts)) {\n // Try to recover — reset timeout state to give session a fresh window.\n // This helps survive sleep/wake scenarios where TCP connection may still be alive.\n logger.info(`timeout recovery attempt ${this.coordinator.timeoutRecoveryAttempts}, resetting timeout state`)\n sessionState.lastTestRequestAt = null\n sessionState.lastReceivedAt = new Date()\n this.setState(SessionState.ActiveNormalSession)\n } else {\n logger.info(sessionState.toString())\n this.terminate(new Error(`${application?.name}: peer not responding`))\n }\n break\n }\n\n case TickAction.Stop: {\n logger.info(sessionState.toString())\n logger.info('stopping')\n this.stop()\n break\n }\n\n default:\n throw new Error('unexpected action')\n }\n }\n}\n"]}
@@ -5,6 +5,9 @@ export interface IMsgApplication {
5
5
  readonly type: string;
6
6
  readonly resilient: boolean;
7
7
  readonly reconnectSeconds: number;
8
+ readonly connectTimeoutSeconds?: number;
9
+ readonly recoveryAttemptSeconds?: number;
10
+ readonly backoffFailConnectSeconds?: number;
8
11
  readonly tcp?: ITcpTransportDescription;
9
12
  readonly http?: IHttpTransportDescription;
10
13
  readonly protocol: string;
@@ -1 +1 @@
1
- {"version":3,"file":"msg-application.js","sourceRoot":"","sources":["../../src/transport/msg-application.ts"],"names":[],"mappings":"","sourcesContent":["import { ITcpTransportDescription } from './tcp/tcp-transport-description'\nimport { IHttpTransportDescription } from './http/http-transport-description'\n\nexport interface IMsgApplication {\n readonly name: string\n readonly type: string\n readonly resilient: boolean\n readonly reconnectSeconds: number\n readonly tcp?: ITcpTransportDescription\n readonly http?: IHttpTransportDescription\n readonly protocol: string\n readonly dictionary: string\n}\n"]}
1
+ {"version":3,"file":"msg-application.js","sourceRoot":"","sources":["../../src/transport/msg-application.ts"],"names":[],"mappings":"","sourcesContent":["import { ITcpTransportDescription } from './tcp/tcp-transport-description'\nimport { IHttpTransportDescription } from './http/http-transport-description'\n\nexport interface IMsgApplication {\n readonly name: string\n readonly type: string\n /**\n * An initiator which re-establishes its transport after the connection drops and\n * resumes the same session, rather than ending when the socket does. Defaults to\n * false, which gives a single connection. See \"Reconnecting initiators\" in the\n * README for the retry policy below.\n */\n readonly resilient: boolean\n /** how long to wait between attempts whilst trying to establish a connection. Defaults to 5. */\n readonly reconnectSeconds: number\n /**\n * how long to keep attempting a connection before giving up. Defaults to 60 for a\n * resilient initiator and 22 for a plain one.\n */\n readonly connectTimeoutSeconds?: number\n /** resilient only: how long after losing the transport before trying to get it back. Defaults to 5. */\n readonly recoveryAttemptSeconds?: number\n /** resilient only: how long to wait after a failed recovery before trying again. Defaults to 30. */\n readonly backoffFailConnectSeconds?: number\n readonly tcp?: ITcpTransportDescription\n readonly http?: IHttpTransportDescription\n readonly protocol: string\n readonly dictionary: string\n}\n"]}
@@ -65,5 +65,5 @@ export declare abstract class FixSession extends events.EventEmitter {
65
65
  protected abstract onApplicationMsg(msgType: string, view: MsgView): void;
66
66
  protected abstract onReady(view: MsgView): void;
67
67
  protected abstract onStopped(error?: Error): void;
68
- protected abstract onLogon(view: MsgView, user: string, password: string): boolean;
68
+ protected abstract onLogon(view: MsgView, user: string, password: string): boolean | Promise<boolean>;
69
69
  }
@@ -1 +1 @@
1
- {"version":3,"file":"fix-session.js","sourceRoot":"","sources":["../../../src/transport/session/fix-session.ts"],"names":[],"mappings":"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","sourcesContent":["import { ElasticBuffer, MsgView } from '../../buffer'\nimport { IJsFixConfig, IJsFixLogger } from '../../config'\nimport { FixSessionState } from './fix-session-state'\nimport { MsgTransport } from '../factory'\nimport { MsgTag } from '../../types'\nimport { ILooseObject } from '../../collections/collection'\nimport { SendCallback } from '../send-callback'\n\nimport * as events from 'events'\nimport { SessionState } from './session-state'\nimport { SegmentType } from '../../buffer/segment/segment-type'\n\n/**\n * The set of listeners this session attached to one specific transport.\n *\n * The handlers must be kept as stable references - `EventEmitter.removeListener`\n * matches on identity, so subscribing with a fresh closure and unsubscribing with\n * a method reference silently leaves the listener attached (issue #153). Holding\n * the transport alongside the handlers also lets `unsubscribe` detach from the\n * transport it actually subscribed to, even when `this.transport` has already\n * moved on to a newer connection.\n */\ninterface ITransportSubscription {\n readonly transport: MsgTransport\n readonly rxOnMsg: (msgType: string, view: MsgView) => void\n readonly rxOnError: (e: Error) => void\n readonly rxOnDone: () => void\n readonly rxOnEnd: () => void\n readonly rxOnDecoded: (msgType: string, data: ElasticBuffer, ptr: number) => void\n readonly txOnError: (e: Error) => void\n readonly txOnEncoded: (msgType: string, data: string, hdr: ILooseObject) => void\n}\n\nexport abstract class FixSession extends events.EventEmitter {\n public logReceivedMsgs: boolean = false\n protected timer: NodeJS.Timeout | null = null\n protected transport: MsgTransport | null = null\n private subscription: ITransportSubscription | null = null\n public manageSession: boolean = true\n public checkMsgIntegrity: boolean = false\n protected readonly me: string\n protected readonly initiator: boolean\n protected readonly acceptor: boolean\n protected readonly sessionState: FixSessionState\n /**\n * Not readonly: a wildcard acceptor does not know which counterparty it is\n * serving until the Logon arrives, and every session on that listener would\n * otherwise log under the same name. Rebound once the identity is known.\n */\n protected sessionLogger: IJsFixLogger\n protected requestLogoutType: string\n protected respondLogoutType: string\n protected requestLogonType: string\n\n protected constructor (public readonly config: IJsFixConfig) {\n super()\n const description = config.description\n this.me = description?.application?.name ?? 'me'\n this.sessionState = new FixSessionState(\n {\n heartBeat: config.description.HeartBtInt,\n lastPeerMsgSeqNum: config.description.LastReceivedSeqNum\n })\n this.sessionLogger = config.logFactory.logger(`${this.me}:FixSession`)\n this.initiator = description?.application?.type === 'initiator'\n this.acceptor = !this.initiator\n this.checkMsgIntegrity = this.acceptor\n this.sessionState.compId = description.SenderCompId\n }\n\n stateStr (theState: SessionState): string {\n return SessionState[theState]\n }\n\n assignState (newState: SessionState): void {\n const currentState = this.sessionState.state\n const currentStateStr = this.stateStr(currentState)\n const logger = this.sessionLogger\n const msg = `current state ${currentStateStr} (${currentState}) moves to ${SessionState[newState]} (${newState})`\n logger.info(msg)\n this.sessionState.state = newState\n }\n\n public setState (state: SessionState): void {\n const logger = this.sessionLogger\n const currentState = this.sessionState.state\n const currentStateStr = this.stateStr(currentState)\n if (state === currentState) return\n switch (currentState) {\n case SessionState.ConfirmingLogout:\n case SessionState.Stopped:\n if (state !== SessionState.NetworkConnectionEstablished) {\n logger.info(`ignoring request to change state as now already in ${currentStateStr}`)\n } else {\n this.assignState(state)\n }\n break\n\n default: {\n this.assignState(state)\n }\n }\n }\n\n public getState (): SessionState {\n return this.sessionState.state\n }\n\n public lastSentSeqNum (): number {\n return this.sessionState.lastSentSeqNum()\n }\n\n public lastPeerSeqNum (): number {\n return this.sessionState.lastPeerMsgSeqNum\n }\n\n public sendLogon (): void {\n const lo = this.config.factory?.logon()\n if (lo) {\n this.send(this.requestLogonType, lo)\n }\n }\n\n private async waitPromise (): Promise<number> {\n const logger = this.sessionLogger\n if (this.initiator) {\n // Hook for subclasses to reset sequences when ResetSeqNumFlag=Y is configured —\n // must run after the store is loaded, before sendLogon stamps a seq num.\n await this.onPreLogon()\n }\n return await new Promise<any>((resolve, reject) => {\n if (this.initiator) {\n logger.debug(`initiator sending logon state = ${this.stateString()}`)\n this.sendLogon()\n this.setState(SessionState.InitiationLogonSent)\n } else {\n logger.debug(`acceptor waits for logon state = ${this.stateString()}`)\n this.setState(SessionState.WaitingForALogon)\n }\n\n // Use named handlers and detach BOTH when the promise settles. Only one of\n // 'error'/'done' fires per run; without removing the sibling the unfired\n // listener would leak on every reconnect (issue #146). `once` alone is not\n // enough for the same reason — the sibling never fires, so never self-detaches.\n const cleanup = (): void => {\n this.removeListener('error', onError)\n this.removeListener('done', onDone)\n }\n const onError = (e: Error): void => {\n cleanup()\n // read the logger now, not the one captured when the run started - a\n // wildcard acceptor rebinds it once it knows which peer it is serving\n this.sessionLogger.error(e)\n reject(e)\n }\n const onDone = (): void => {\n cleanup()\n resolve(this.transport?.id)\n }\n\n this.on('error', onError)\n this.on('done', onDone)\n })\n }\n\n public async run (transport: MsgTransport): Promise<number> {\n const logger = this.sessionLogger\n if (this.transport) {\n logger.info(`reset from previous transport. state ${this.stateString()}`)\n this.reset()\n }\n this.transport = transport\n this.subscribe()\n return await this.waitPromise()\n }\n\n protected expectedEndState (): boolean {\n switch (this.sessionState.state) {\n case SessionState.Stopped:\n case SessionState.ConfirmingLogout:\n return true\n\n default:\n return false\n }\n }\n\n protected rxOnEnd (): void {\n const logger = this.sessionLogger\n logger.info(`rx end received sessionState = [${this.sessionState.toString()}]`)\n const expectedState = this.expectedEndState()\n if (expectedState) {\n logger.info(`rx receives end state = ${this.stateString()} - stop session`)\n this.stop()\n } else {\n this.setState(SessionState.DetectBrokenNetworkConnection)\n const e = new Error(`unexpected state - transport failed? = ${this.stateString()}`)\n logger.info(`rx error ${e.message}`)\n this.terminate(e)\n }\n }\n\n protected rxOnMsg (msgType: string, view: MsgView): void {\n const logger = this.sessionLogger\n\n if (this.logReceivedMsgs) {\n const name = view.segment.type !== SegmentType.Unknown ? view?.segment?.set?.name : 'unknown'\n logger.info(`${msgType}: ${name}`)\n logger.info(`${view.toString()}`)\n }\n this.sessionState.lastReceivedAt = new Date()\n if (this.manageSession) {\n this.onMsg(msgType, view)\n } else {\n this.checkForwardMsg(msgType, view)\n }\n }\n\n protected rxOnDone (): void {\n const logger = this.sessionLogger\n logger.info('rx done received')\n this.done()\n }\n\n protected rxOnError (e: Error): void {\n const logger = this.sessionLogger\n logger.warning(`rx error event: ${e.message} ${JSON.stringify(e)}`)\n this.terminate(e)\n }\n\n protected rxOnDecoded (msgType: string, data: ElasticBuffer, ptr: number): void {\n const logger = this.sessionLogger\n logger.debug(`rx: [${msgType}] ${ptr} bytes`)\n this.onDecoded(msgType, data.toString(ptr))\n }\n\n protected txOnError (e: Error): void {\n const logger = this.sessionLogger\n logger.warning(`tx error event: ${e.message} ${JSON.stringify(e)}`)\n this.terminate(e)\n }\n\n protected txOnEncoded (msgType: string, data: string, hdr: ILooseObject): void {\n const logger = this.sessionLogger\n this.sessionState.lastHeader = hdr\n logger.debug(`tx: [${msgType}] ${data.length} bytes seqNo = ${this.lastSentSeqNum()}`)\n this.onEncoded(msgType, data)\n }\n\n /**\n * true when the event which has just fired came from the transport this session\n * is currently running. A half open socket can keep emitting long after the peer\n * has reconnected on a fresh connection - those events must not be allowed to drive\n * the live session (issue #153).\n */\n private isCurrentTransport (transport: MsgTransport, event: string): boolean {\n if (this.subscription?.transport === transport && this.transport === transport) {\n return true\n }\n const current = this.transport?.id ?? 'none'\n this.sessionLogger.warning(`ignoring '${event}' from stale transport ${transport.id} - current transport is ${current}`)\n return false\n }\n\n protected unsubscribe (): void {\n const logger = this.sessionLogger\n const subscription = this.subscription\n if (!subscription) {\n logger.debug('unsubscribe called with no active subscription')\n return\n }\n const transport = subscription.transport\n logger.info(`unsubscribe transport ${transport.id} sessionState = [${this.sessionState.toString()}]`)\n const rx = transport.receiver\n const tx = transport.transmitter\n\n rx?.removeListener('msg', subscription.rxOnMsg)\n rx?.removeListener('error', subscription.rxOnError)\n rx?.removeListener('done', subscription.rxOnDone)\n rx?.removeListener('end', subscription.rxOnEnd)\n rx?.removeListener('decoded', subscription.rxOnDecoded)\n tx?.removeListener('error', subscription.txOnError)\n tx?.removeListener('encoded', subscription.txOnEncoded)\n this.subscription = null\n logger.debug(`unsubscribe complete - rx listeners now ${rx?.listenerCount('msg') ?? 0} msg, ${rx?.listenerCount('end') ?? 0} end`)\n }\n\n protected subscribe (): void {\n const transport = this.transport\n if (!transport) {\n this.sessionLogger.warning('subscribe called with no transport')\n return\n }\n // detach from any previous transport before attaching to this one\n if (this.subscription) {\n this.unsubscribe()\n }\n const inst = this\n const subscription: ITransportSubscription = {\n transport,\n rxOnMsg: (msgType: string, view: MsgView) => {\n if (inst.isCurrentTransport(transport, 'msg')) inst.rxOnMsg(msgType, view)\n },\n rxOnError: (e: Error) => {\n if (inst.isCurrentTransport(transport, 'error')) inst.rxOnError(e)\n },\n rxOnDone: () => {\n if (inst.isCurrentTransport(transport, 'done')) inst.rxOnDone()\n },\n rxOnEnd: () => {\n if (inst.isCurrentTransport(transport, 'end')) inst.rxOnEnd()\n },\n rxOnDecoded: (msgType: string, data: ElasticBuffer, ptr: number) => {\n if (inst.isCurrentTransport(transport, 'decoded')) inst.rxOnDecoded(msgType, data, ptr)\n },\n txOnError: (e: Error) => {\n if (inst.isCurrentTransport(transport, 'tx error')) inst.txOnError(e)\n },\n txOnEncoded: (msgType: string, data: string, hdr: ILooseObject) => {\n if (inst.isCurrentTransport(transport, 'encoded')) inst.txOnEncoded(msgType, data, hdr)\n }\n }\n const rx = transport.receiver\n const tx = transport.transmitter\n rx?.on('msg', subscription.rxOnMsg)\n rx?.on('error', subscription.rxOnError)\n rx?.on('done', subscription.rxOnDone)\n rx?.on('end', subscription.rxOnEnd)\n rx?.on('decoded', subscription.rxOnDecoded)\n tx?.on('error', subscription.txOnError)\n tx?.on('encoded', subscription.txOnEncoded)\n this.subscription = subscription\n this.sessionLogger.info(`subscribed to transport ${transport.id}`)\n }\n\n protected validStateApplicationMsg (): boolean {\n switch (this.sessionState.state) {\n case SessionState.Idle:\n case SessionState.InitiateConnection:\n case SessionState.InitiationLogonSent:\n case SessionState.WaitingForALogon:\n case SessionState.HandleResendRequest:\n case SessionState.AwaitingProcessingResponseToTestRequest:\n case SessionState.AwaitingProcessingResponseToResendRequest:\n return false\n default:\n return true\n }\n }\n\n protected stateString (): string {\n return SessionState[this.sessionState.state]\n }\n\n protected checkForwardMsg (msgType: string, view: MsgView): void {\n this.sessionLogger.info(`forwarding msgType = '${msgType}' to application`)\n this.setState(SessionState.ActiveNormalSession)\n this.onApplicationMsg(msgType, view)\n }\n\n private stopTimer (): void {\n if (this.timer) {\n this.sessionLogger.info('stopTimer')\n clearInterval(this.timer)\n this.timer = null\n }\n }\n\n protected terminate (error: Error): void {\n if (this.sessionState.state === SessionState.Stopped) return\n this.sessionLogger.error(error)\n this.stopTimer()\n this.unsubscribe()\n if (this.transport) {\n this.sessionLogger.info(`terminate: kill transport ${this.transport.id}`)\n this.transport.end()\n }\n this.transport = null\n this.setState(SessionState.Stopped)\n this.onSessionStopping()\n this.emit('error', error)\n this.onStopped(error)\n }\n\n protected peerLogout (view: MsgView): void {\n const msg = view.getString(MsgTag.Text)\n const state = this.sessionState.state\n switch (state) {\n case SessionState.WaitingLogoutConfirm: {\n this.sessionLogger.info(`peer confirms logout Text = '${msg}'`)\n this.stop()\n break\n }\n\n case SessionState.InitiationLogonResponse:\n case SessionState.ActiveNormalSession:\n case SessionState.InitiationLogonReceived: {\n this.setState(SessionState.ConfirmingLogout)\n this.sessionLogger.info(`peer initiates logout Text = '${msg}'`)\n this.sessionLogout()\n }\n }\n }\n\n /**\n * @param callback optional, invoked once the message has been encoded and handed to\n * the transport, or as soon as that fails. Without it a send is fire and forget:\n * nothing tells the caller which sequence number the message went out under, and a\n * message dropped because the session is down, or refused by the encoder, goes\n * unanswered. See https://github.com/TimelordUK/jspurefix/issues/86\n */\n protected send (msgType: string, obj: ILooseObject, callback: SendCallback | null = null): void {\n const state = this.sessionState.state\n switch (state) {\n case SessionState.Stopped: {\n const msg = `can't send in state ${this.stateString()}`\n this.sessionLogger.warning(msg)\n // the message is dropped either way - but a caller that asked to be told is\n // now told, instead of watching for a log line\n callback?.(new Error(msg), { msgType, header: null, encoded: null })\n break\n }\n\n default: {\n this.sessionState.LastSentAt = new Date()\n const transmitter = this.transport?.transmitter\n if (!transmitter) {\n const msg = `no transport to send ${msgType} on`\n this.sessionLogger.warning(msg)\n callback?.(new Error(msg), { msgType, header: null, encoded: null })\n break\n }\n transmitter.send(msgType, obj, callback)\n break\n }\n }\n }\n\n protected sendLogout (msg: string): void {\n const factory = this.config.factory\n this.sessionLogger.info(`sending logout with ${msg}`)\n const lo = factory?.logout(this.requestLogoutType, msg)\n if (lo) {\n this.send(this.requestLogoutType, lo)\n }\n }\n\n protected sessionLogout (): void {\n const sessionState = this.sessionState\n if (sessionState.logoutSentAt) {\n return\n }\n\n switch (sessionState.state) {\n case SessionState.ActiveNormalSession:\n case SessionState.InitiationLogonResponse:\n case SessionState.InitiationLogonReceived: {\n // this instance initiates logout\n this.setState(SessionState.WaitingLogoutConfirm)\n sessionState.logoutSentAt = new Date()\n const msg = `${this.me} initiate logout`\n this.sessionLogger.info(msg)\n this.sendLogout(msg)\n break\n }\n\n case SessionState.ConfirmingLogout: {\n // this instance responds to log out\n this.setState(SessionState.ConfirmingLogout)\n sessionState.logoutSentAt = new Date()\n const msg = `${this.me} confirming logout`\n this.sessionLogger.info(msg)\n this.sendLogout(msg)\n break\n }\n\n default: {\n this.sessionLogger.info(`sessionLogout ignored as in state ${sessionState.state}`)\n }\n }\n }\n\n public done (): void {\n switch (this.sessionState.state) {\n case SessionState.InitiationLogonResponse:\n case SessionState.ActiveNormalSession:\n case SessionState.InitiationLogonReceived: {\n this.sessionLogout()\n break\n }\n\n case SessionState.Stopped:\n this.sessionLogger.info('done. session is now stopped')\n break\n\n default: {\n this.stop()\n break\n }\n }\n this.sessionLogger.info(`done. check logout sequence state ${this.stateString()}`)\n }\n\n public reset (resetSeqNum?: number | null): void {\n this.stopTimer()\n // unsubscribe from old transport before clearing reference\n this.unsubscribe()\n // reset parser to clear any partial message state from dropped connection\n const receiver: any = this.transport?.receiver\n if (receiver?.reset) {\n receiver.reset()\n }\n this.transport = null\n const resetFlag = this.config.description.ResetSeqNumFlag\n const seqNum = resetFlag ? 0 : resetSeqNum ?? this.sessionState.lastPeerMsgSeqNum\n this.sessionState.reset(seqNum) // from header def ... eventually\n this.onPrepareForReconnect()\n this.setState(SessionState.NetworkConnectionEstablished)\n }\n\n protected onPrepareForReconnect (): void {\n // Override in subclass to reset coordinator/transient state\n }\n\n /**\n * Called once as the session moves to Stopped, before the application is informed\n * via onStopped. Override to release session scoped resources - the ascii session\n * uses this to remove itself from the session registry. Mirrors cspurefix\n * FixSession.OnSessionStopping.\n */\n protected onSessionStopping (): void {\n // Default no-op\n }\n\n /**\n * Called for initiators after the store is loaded but before the Logon is sent.\n * Override to reset sequences/store when ResetSeqNumFlag=Y so the Logon goes out\n * with MsgSeqNum=1 instead of the recovered sender seq num.\n */\n protected async onPreLogon (): Promise<void> {\n // Default no-op\n }\n\n /**\n * Stop this session on behalf of an external caller - typically the session registry\n * when a new connection for the same SessionId replaces this one, but equally an\n * application which has decided the peer is gone. Mirrors cspurefix\n * FixSession.RequestStop.\n * @param reason recorded in the session log and carried on the emitted error\n */\n public requestStop (reason: string): void {\n this.sessionLogger.info(`requestStop: ${reason}`)\n this.stop(new Error(reason))\n }\n\n protected stop (error: Error | null = null): void {\n if (this.sessionState.state === SessionState.Stopped) {\n return\n }\n this.stopTimer()\n this.unsubscribe()\n this.sessionLogger.info(`stop: kill transport ${this.transport?.id ?? 'none'}`)\n this.onSessionStopping()\n this.transport?.end()\n if (error) {\n this.sessionLogger.info(`stop: emit error ${error.message}`)\n this.emit('error', error)\n } else {\n this.emit('done')\n }\n\n this.setState(SessionState.Stopped)\n this.onStopped(error ?? undefined)\n this.transport = null\n }\n\n /**\n * dispatches a message into the subclass that inherits from FixSession. The view contains\n * the parsed message which has utility methods such as toObject(). The Ascii session provides\n * an implementation to handle admin level messages such as logon, hearbeat and resest request.\n * Any application messges are dispatched via onApplicationMsg where the application can action\n * the message.\n * @param msgType the string based msg type the view represents\n * @param view container for all parsed fields representing the received message.\n * @protected\n */\n protected abstract onMsg (msgType: string, view: MsgView): void\n /**\n * the parsed txt recieved from the peer application. Given the applicaton is\n * responible for maintaining the fix log, this can be used to persist all received\n * messages.\n * @param msgType the string based msg type the view represents\n * @param txt the received message where for Ascii, the wire SOH delimeter is replaced\n * with that specified in the config e.g. '|'\n * @protected\n */\n protected abstract onDecoded (msgType: string, txt: string): void\n /**\n * the formatted txt sent to the peer application as an outbound message. Given the applicaton is\n * responible for maintaining the fix log, this can be used to persist all transmitted\n * messages. use msgType for example to persist only trade capture messages to database\n * @param msgType the msg type representing the message.\n * @param txt the sent message where for Ascii, the wire SOH delimeter is replaced\n * with that specified in the config e.g. '|'\n * @protected\n */\n protected abstract onEncoded (msgType: string, txt: string): void\n /**\n * typically all session level messages are handled by AsciiSession and these are\n * application level such as MarketDataRefresh. This will represent the applications main\n * work functiono where responses can be sent back to the peer. If manageSession has been set false\n * (not recommended) all messages are sent to this function\n * @param msgType the msg type representing the message.\n * @param view a wrapper containing the parsed message received.\n * @protected\n */\n protected abstract onApplicationMsg (msgType: string, view: MsgView): void\n /**\n * at this point the application is ready to send messages - peer login has been achieved\n * and the session can be considered ready to use. In the case of an initiator the application\n * may at this point send for security definitions or send market data subscriptions\n * @param view the login message causing session to be ready\n * @protected\n */\n protected abstract onReady (view: MsgView): void\n\n /**\n * Inform application this session has now ended - either from logout or connection dropped\n * @param error if session has been terminated via an error it is provided\n * @protected\n */\n protected abstract onStopped (error?: Error): void\n /**\n * Placeholder infomring the application of a peer login attempt.\n * @param view the login message\n * @param user extracted user from message\n * @param password extracted password from the message.\n * @protected\n */\n protected abstract onLogon (view: MsgView, user: string, password: string): boolean\n}\n"]}
1
+ {"version":3,"file":"fix-session.js","sourceRoot":"","sources":["../../../src/transport/session/fix-session.ts"],"names":[],"mappings":"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","sourcesContent":["import { ElasticBuffer, MsgView } from '../../buffer'\nimport { IJsFixConfig, IJsFixLogger } from '../../config'\nimport { FixSessionState } from './fix-session-state'\nimport { MsgTransport } from '../factory'\nimport { MsgTag } from '../../types'\nimport { ILooseObject } from '../../collections/collection'\nimport { SendCallback } from '../send-callback'\n\nimport * as events from 'events'\nimport { SessionState } from './session-state'\nimport { SegmentType } from '../../buffer/segment/segment-type'\n\n/**\n * The set of listeners this session attached to one specific transport.\n *\n * The handlers must be kept as stable references - `EventEmitter.removeListener`\n * matches on identity, so subscribing with a fresh closure and unsubscribing with\n * a method reference silently leaves the listener attached (issue #153). Holding\n * the transport alongside the handlers also lets `unsubscribe` detach from the\n * transport it actually subscribed to, even when `this.transport` has already\n * moved on to a newer connection.\n */\ninterface ITransportSubscription {\n readonly transport: MsgTransport\n readonly rxOnMsg: (msgType: string, view: MsgView) => void\n readonly rxOnError: (e: Error) => void\n readonly rxOnDone: () => void\n readonly rxOnEnd: () => void\n readonly rxOnDecoded: (msgType: string, data: ElasticBuffer, ptr: number) => void\n readonly txOnError: (e: Error) => void\n readonly txOnEncoded: (msgType: string, data: string, hdr: ILooseObject) => void\n}\n\nexport abstract class FixSession extends events.EventEmitter {\n public logReceivedMsgs: boolean = false\n protected timer: NodeJS.Timeout | null = null\n protected transport: MsgTransport | null = null\n private subscription: ITransportSubscription | null = null\n public manageSession: boolean = true\n public checkMsgIntegrity: boolean = false\n protected readonly me: string\n protected readonly initiator: boolean\n protected readonly acceptor: boolean\n protected readonly sessionState: FixSessionState\n /**\n * Not readonly: a wildcard acceptor does not know which counterparty it is\n * serving until the Logon arrives, and every session on that listener would\n * otherwise log under the same name. Rebound once the identity is known.\n */\n protected sessionLogger: IJsFixLogger\n protected requestLogoutType: string\n protected respondLogoutType: string\n protected requestLogonType: string\n\n protected constructor (public readonly config: IJsFixConfig) {\n super()\n const description = config.description\n this.me = description?.application?.name ?? 'me'\n this.sessionState = new FixSessionState(\n {\n heartBeat: config.description.HeartBtInt,\n lastPeerMsgSeqNum: config.description.LastReceivedSeqNum\n })\n this.sessionLogger = config.logFactory.logger(`${this.me}:FixSession`)\n this.initiator = description?.application?.type === 'initiator'\n this.acceptor = !this.initiator\n this.checkMsgIntegrity = this.acceptor\n this.sessionState.compId = description.SenderCompId\n }\n\n stateStr (theState: SessionState): string {\n return SessionState[theState]\n }\n\n assignState (newState: SessionState): void {\n const currentState = this.sessionState.state\n const currentStateStr = this.stateStr(currentState)\n const logger = this.sessionLogger\n const msg = `current state ${currentStateStr} (${currentState}) moves to ${SessionState[newState]} (${newState})`\n logger.info(msg)\n this.sessionState.state = newState\n }\n\n public setState (state: SessionState): void {\n const logger = this.sessionLogger\n const currentState = this.sessionState.state\n const currentStateStr = this.stateStr(currentState)\n if (state === currentState) return\n switch (currentState) {\n case SessionState.ConfirmingLogout:\n case SessionState.Stopped:\n if (state !== SessionState.NetworkConnectionEstablished) {\n logger.info(`ignoring request to change state as now already in ${currentStateStr}`)\n } else {\n this.assignState(state)\n }\n break\n\n default: {\n this.assignState(state)\n }\n }\n }\n\n public getState (): SessionState {\n return this.sessionState.state\n }\n\n public lastSentSeqNum (): number {\n return this.sessionState.lastSentSeqNum()\n }\n\n public lastPeerSeqNum (): number {\n return this.sessionState.lastPeerMsgSeqNum\n }\n\n public sendLogon (): void {\n const lo = this.config.factory?.logon()\n if (lo) {\n this.send(this.requestLogonType, lo)\n }\n }\n\n private async waitPromise (): Promise<number> {\n const logger = this.sessionLogger\n if (this.initiator) {\n // Hook for subclasses to reset sequences when ResetSeqNumFlag=Y is configured —\n // must run after the store is loaded, before sendLogon stamps a seq num.\n await this.onPreLogon()\n }\n return await new Promise<any>((resolve, reject) => {\n if (this.initiator) {\n logger.debug(`initiator sending logon state = ${this.stateString()}`)\n this.sendLogon()\n this.setState(SessionState.InitiationLogonSent)\n } else {\n logger.debug(`acceptor waits for logon state = ${this.stateString()}`)\n this.setState(SessionState.WaitingForALogon)\n }\n\n // Use named handlers and detach BOTH when the promise settles. Only one of\n // 'error'/'done' fires per run; without removing the sibling the unfired\n // listener would leak on every reconnect (issue #146). `once` alone is not\n // enough for the same reason — the sibling never fires, so never self-detaches.\n const cleanup = (): void => {\n this.removeListener('error', onError)\n this.removeListener('done', onDone)\n }\n const onError = (e: Error): void => {\n cleanup()\n // read the logger now, not the one captured when the run started - a\n // wildcard acceptor rebinds it once it knows which peer it is serving\n this.sessionLogger.error(e)\n reject(e)\n }\n const onDone = (): void => {\n cleanup()\n resolve(this.transport?.id)\n }\n\n this.on('error', onError)\n this.on('done', onDone)\n })\n }\n\n public async run (transport: MsgTransport): Promise<number> {\n const logger = this.sessionLogger\n if (this.transport) {\n logger.info(`reset from previous transport. state ${this.stateString()}`)\n this.reset()\n }\n this.transport = transport\n this.subscribe()\n return await this.waitPromise()\n }\n\n protected expectedEndState (): boolean {\n switch (this.sessionState.state) {\n case SessionState.Stopped:\n case SessionState.ConfirmingLogout:\n return true\n\n default:\n return false\n }\n }\n\n protected rxOnEnd (): void {\n const logger = this.sessionLogger\n logger.info(`rx end received sessionState = [${this.sessionState.toString()}]`)\n const expectedState = this.expectedEndState()\n if (expectedState) {\n logger.info(`rx receives end state = ${this.stateString()} - stop session`)\n this.stop()\n } else {\n this.setState(SessionState.DetectBrokenNetworkConnection)\n const e = new Error(`unexpected state - transport failed? = ${this.stateString()}`)\n logger.info(`rx error ${e.message}`)\n this.terminate(e)\n }\n }\n\n protected rxOnMsg (msgType: string, view: MsgView): void {\n const logger = this.sessionLogger\n\n if (this.logReceivedMsgs) {\n const name = view.segment.type !== SegmentType.Unknown ? view?.segment?.set?.name : 'unknown'\n logger.info(`${msgType}: ${name}`)\n logger.info(`${view.toString()}`)\n }\n this.sessionState.lastReceivedAt = new Date()\n if (this.manageSession) {\n this.onMsg(msgType, view)\n } else {\n this.checkForwardMsg(msgType, view)\n }\n }\n\n protected rxOnDone (): void {\n const logger = this.sessionLogger\n logger.info('rx done received')\n this.done()\n }\n\n protected rxOnError (e: Error): void {\n const logger = this.sessionLogger\n logger.warning(`rx error event: ${e.message} ${JSON.stringify(e)}`)\n this.terminate(e)\n }\n\n protected rxOnDecoded (msgType: string, data: ElasticBuffer, ptr: number): void {\n const logger = this.sessionLogger\n logger.debug(`rx: [${msgType}] ${ptr} bytes`)\n this.onDecoded(msgType, data.toString(ptr))\n }\n\n protected txOnError (e: Error): void {\n const logger = this.sessionLogger\n logger.warning(`tx error event: ${e.message} ${JSON.stringify(e)}`)\n this.terminate(e)\n }\n\n protected txOnEncoded (msgType: string, data: string, hdr: ILooseObject): void {\n const logger = this.sessionLogger\n this.sessionState.lastHeader = hdr\n logger.debug(`tx: [${msgType}] ${data.length} bytes seqNo = ${this.lastSentSeqNum()}`)\n this.onEncoded(msgType, data)\n }\n\n /**\n * true when the event which has just fired came from the transport this session\n * is currently running. A half open socket can keep emitting long after the peer\n * has reconnected on a fresh connection - those events must not be allowed to drive\n * the live session (issue #153).\n */\n private isCurrentTransport (transport: MsgTransport, event: string): boolean {\n if (this.subscription?.transport === transport && this.transport === transport) {\n return true\n }\n const current = this.transport?.id ?? 'none'\n this.sessionLogger.warning(`ignoring '${event}' from stale transport ${transport.id} - current transport is ${current}`)\n return false\n }\n\n protected unsubscribe (): void {\n const logger = this.sessionLogger\n const subscription = this.subscription\n if (!subscription) {\n logger.debug('unsubscribe called with no active subscription')\n return\n }\n const transport = subscription.transport\n logger.info(`unsubscribe transport ${transport.id} sessionState = [${this.sessionState.toString()}]`)\n const rx = transport.receiver\n const tx = transport.transmitter\n\n rx?.removeListener('msg', subscription.rxOnMsg)\n rx?.removeListener('error', subscription.rxOnError)\n rx?.removeListener('done', subscription.rxOnDone)\n rx?.removeListener('end', subscription.rxOnEnd)\n rx?.removeListener('decoded', subscription.rxOnDecoded)\n tx?.removeListener('error', subscription.txOnError)\n tx?.removeListener('encoded', subscription.txOnEncoded)\n this.subscription = null\n logger.debug(`unsubscribe complete - rx listeners now ${rx?.listenerCount('msg') ?? 0} msg, ${rx?.listenerCount('end') ?? 0} end`)\n }\n\n protected subscribe (): void {\n const transport = this.transport\n if (!transport) {\n this.sessionLogger.warning('subscribe called with no transport')\n return\n }\n // detach from any previous transport before attaching to this one\n if (this.subscription) {\n this.unsubscribe()\n }\n const inst = this\n const subscription: ITransportSubscription = {\n transport,\n rxOnMsg: (msgType: string, view: MsgView) => {\n if (inst.isCurrentTransport(transport, 'msg')) inst.rxOnMsg(msgType, view)\n },\n rxOnError: (e: Error) => {\n if (inst.isCurrentTransport(transport, 'error')) inst.rxOnError(e)\n },\n rxOnDone: () => {\n if (inst.isCurrentTransport(transport, 'done')) inst.rxOnDone()\n },\n rxOnEnd: () => {\n if (inst.isCurrentTransport(transport, 'end')) inst.rxOnEnd()\n },\n rxOnDecoded: (msgType: string, data: ElasticBuffer, ptr: number) => {\n if (inst.isCurrentTransport(transport, 'decoded')) inst.rxOnDecoded(msgType, data, ptr)\n },\n txOnError: (e: Error) => {\n if (inst.isCurrentTransport(transport, 'tx error')) inst.txOnError(e)\n },\n txOnEncoded: (msgType: string, data: string, hdr: ILooseObject) => {\n if (inst.isCurrentTransport(transport, 'encoded')) inst.txOnEncoded(msgType, data, hdr)\n }\n }\n const rx = transport.receiver\n const tx = transport.transmitter\n rx?.on('msg', subscription.rxOnMsg)\n rx?.on('error', subscription.rxOnError)\n rx?.on('done', subscription.rxOnDone)\n rx?.on('end', subscription.rxOnEnd)\n rx?.on('decoded', subscription.rxOnDecoded)\n tx?.on('error', subscription.txOnError)\n tx?.on('encoded', subscription.txOnEncoded)\n this.subscription = subscription\n this.sessionLogger.info(`subscribed to transport ${transport.id}`)\n }\n\n protected validStateApplicationMsg (): boolean {\n switch (this.sessionState.state) {\n case SessionState.Idle:\n case SessionState.InitiateConnection:\n case SessionState.InitiationLogonSent:\n case SessionState.WaitingForALogon:\n case SessionState.HandleResendRequest:\n case SessionState.AwaitingProcessingResponseToTestRequest:\n case SessionState.AwaitingProcessingResponseToResendRequest:\n return false\n default:\n return true\n }\n }\n\n protected stateString (): string {\n return SessionState[this.sessionState.state]\n }\n\n protected checkForwardMsg (msgType: string, view: MsgView): void {\n this.sessionLogger.info(`forwarding msgType = '${msgType}' to application`)\n this.setState(SessionState.ActiveNormalSession)\n this.onApplicationMsg(msgType, view)\n }\n\n private stopTimer (): void {\n if (this.timer) {\n this.sessionLogger.info('stopTimer')\n clearInterval(this.timer)\n this.timer = null\n }\n }\n\n protected terminate (error: Error): void {\n if (this.sessionState.state === SessionState.Stopped) return\n this.sessionLogger.error(error)\n this.stopTimer()\n this.unsubscribe()\n if (this.transport) {\n this.sessionLogger.info(`terminate: kill transport ${this.transport.id}`)\n this.transport.end()\n }\n this.transport = null\n this.setState(SessionState.Stopped)\n this.onSessionStopping()\n this.emit('error', error)\n this.onStopped(error)\n }\n\n protected peerLogout (view: MsgView): void {\n const msg = view.getString(MsgTag.Text)\n const state = this.sessionState.state\n switch (state) {\n case SessionState.WaitingLogoutConfirm: {\n this.sessionLogger.info(`peer confirms logout Text = '${msg}'`)\n this.stop()\n break\n }\n\n case SessionState.InitiationLogonResponse:\n case SessionState.ActiveNormalSession:\n case SessionState.InitiationLogonReceived: {\n this.setState(SessionState.ConfirmingLogout)\n this.sessionLogger.info(`peer initiates logout Text = '${msg}'`)\n this.sessionLogout()\n }\n }\n }\n\n /**\n * @param callback optional, invoked once the message has been encoded and handed to\n * the transport, or as soon as that fails. Without it a send is fire and forget:\n * nothing tells the caller which sequence number the message went out under, and a\n * message dropped because the session is down, or refused by the encoder, goes\n * unanswered. See https://github.com/TimelordUK/jspurefix/issues/86\n */\n protected send (msgType: string, obj: ILooseObject, callback: SendCallback | null = null): void {\n const state = this.sessionState.state\n switch (state) {\n case SessionState.Stopped: {\n const msg = `can't send in state ${this.stateString()}`\n this.sessionLogger.warning(msg)\n // the message is dropped either way - but a caller that asked to be told is\n // now told, instead of watching for a log line\n callback?.(new Error(msg), { msgType, header: null, encoded: null })\n break\n }\n\n default: {\n this.sessionState.LastSentAt = new Date()\n const transmitter = this.transport?.transmitter\n if (!transmitter) {\n const msg = `no transport to send ${msgType} on`\n this.sessionLogger.warning(msg)\n callback?.(new Error(msg), { msgType, header: null, encoded: null })\n break\n }\n transmitter.send(msgType, obj, callback)\n break\n }\n }\n }\n\n protected sendLogout (msg: string): void {\n const factory = this.config.factory\n this.sessionLogger.info(`sending logout with ${msg}`)\n const lo = factory?.logout(this.requestLogoutType, msg)\n if (lo) {\n this.send(this.requestLogoutType, lo)\n }\n }\n\n protected sessionLogout (): void {\n const sessionState = this.sessionState\n if (sessionState.logoutSentAt) {\n return\n }\n\n switch (sessionState.state) {\n case SessionState.ActiveNormalSession:\n case SessionState.InitiationLogonResponse:\n case SessionState.InitiationLogonReceived: {\n // this instance initiates logout\n this.setState(SessionState.WaitingLogoutConfirm)\n sessionState.logoutSentAt = new Date()\n const msg = `${this.me} initiate logout`\n this.sessionLogger.info(msg)\n this.sendLogout(msg)\n break\n }\n\n case SessionState.ConfirmingLogout: {\n // this instance responds to log out\n this.setState(SessionState.ConfirmingLogout)\n sessionState.logoutSentAt = new Date()\n const msg = `${this.me} confirming logout`\n this.sessionLogger.info(msg)\n this.sendLogout(msg)\n break\n }\n\n default: {\n this.sessionLogger.info(`sessionLogout ignored as in state ${sessionState.state}`)\n }\n }\n }\n\n public done (): void {\n switch (this.sessionState.state) {\n case SessionState.InitiationLogonResponse:\n case SessionState.ActiveNormalSession:\n case SessionState.InitiationLogonReceived: {\n this.sessionLogout()\n break\n }\n\n case SessionState.Stopped:\n this.sessionLogger.info('done. session is now stopped')\n break\n\n default: {\n this.stop()\n break\n }\n }\n this.sessionLogger.info(`done. check logout sequence state ${this.stateString()}`)\n }\n\n public reset (resetSeqNum?: number | null): void {\n this.stopTimer()\n // unsubscribe from old transport before clearing reference\n this.unsubscribe()\n // reset parser to clear any partial message state from dropped connection\n const receiver: any = this.transport?.receiver\n if (receiver?.reset) {\n receiver.reset()\n }\n this.transport = null\n const resetFlag = this.config.description.ResetSeqNumFlag\n const seqNum = resetFlag ? 0 : resetSeqNum ?? this.sessionState.lastPeerMsgSeqNum\n this.sessionState.reset(seqNum) // from header def ... eventually\n this.onPrepareForReconnect()\n this.setState(SessionState.NetworkConnectionEstablished)\n }\n\n protected onPrepareForReconnect (): void {\n // Override in subclass to reset coordinator/transient state\n }\n\n /**\n * Called once as the session moves to Stopped, before the application is informed\n * via onStopped. Override to release session scoped resources - the ascii session\n * uses this to remove itself from the session registry. Mirrors cspurefix\n * FixSession.OnSessionStopping.\n */\n protected onSessionStopping (): void {\n // Default no-op\n }\n\n /**\n * Called for initiators after the store is loaded but before the Logon is sent.\n * Override to reset sequences/store when ResetSeqNumFlag=Y so the Logon goes out\n * with MsgSeqNum=1 instead of the recovered sender seq num.\n */\n protected async onPreLogon (): Promise<void> {\n // Default no-op\n }\n\n /**\n * Stop this session on behalf of an external caller - typically the session registry\n * when a new connection for the same SessionId replaces this one, but equally an\n * application which has decided the peer is gone. Mirrors cspurefix\n * FixSession.RequestStop.\n * @param reason recorded in the session log and carried on the emitted error\n */\n public requestStop (reason: string): void {\n this.sessionLogger.info(`requestStop: ${reason}`)\n this.stop(new Error(reason))\n }\n\n protected stop (error: Error | null = null): void {\n if (this.sessionState.state === SessionState.Stopped) {\n return\n }\n this.stopTimer()\n this.unsubscribe()\n this.sessionLogger.info(`stop: kill transport ${this.transport?.id ?? 'none'}`)\n this.onSessionStopping()\n this.transport?.end()\n if (error) {\n this.sessionLogger.info(`stop: emit error ${error.message}`)\n this.emit('error', error)\n } else {\n this.emit('done')\n }\n\n this.setState(SessionState.Stopped)\n this.onStopped(error ?? undefined)\n this.transport = null\n }\n\n /**\n * dispatches a message into the subclass that inherits from FixSession. The view contains\n * the parsed message which has utility methods such as toObject(). The Ascii session provides\n * an implementation to handle admin level messages such as logon, hearbeat and resest request.\n * Any application messges are dispatched via onApplicationMsg where the application can action\n * the message.\n * @param msgType the string based msg type the view represents\n * @param view container for all parsed fields representing the received message.\n * @protected\n */\n protected abstract onMsg (msgType: string, view: MsgView): void\n /**\n * the parsed txt recieved from the peer application. Given the applicaton is\n * responible for maintaining the fix log, this can be used to persist all received\n * messages.\n * @param msgType the string based msg type the view represents\n * @param txt the received message where for Ascii, the wire SOH delimeter is replaced\n * with that specified in the config e.g. '|'\n * @protected\n */\n protected abstract onDecoded (msgType: string, txt: string): void\n /**\n * the formatted txt sent to the peer application as an outbound message. Given the applicaton is\n * responible for maintaining the fix log, this can be used to persist all transmitted\n * messages. use msgType for example to persist only trade capture messages to database\n * @param msgType the msg type representing the message.\n * @param txt the sent message where for Ascii, the wire SOH delimeter is replaced\n * with that specified in the config e.g. '|'\n * @protected\n */\n protected abstract onEncoded (msgType: string, txt: string): void\n /**\n * typically all session level messages are handled by AsciiSession and these are\n * application level such as MarketDataRefresh. This will represent the applications main\n * work functiono where responses can be sent back to the peer. If manageSession has been set false\n * (not recommended) all messages are sent to this function\n * @param msgType the msg type representing the message.\n * @param view a wrapper containing the parsed message received.\n * @protected\n */\n protected abstract onApplicationMsg (msgType: string, view: MsgView): void\n /**\n * at this point the application is ready to send messages - peer login has been achieved\n * and the session can be considered ready to use. In the case of an initiator the application\n * may at this point send for security definitions or send market data subscriptions\n * @param view the login message causing session to be ready\n * @protected\n */\n protected abstract onReady (view: MsgView): void\n\n /**\n * Inform application this session has now ended - either from logout or connection dropped\n * @param error if session has been terminated via an error it is provided\n * @protected\n */\n protected abstract onStopped (error?: Error): void\n /**\n * Inform the application of a peer login attempt and ask it to accept or reject.\n *\n * Return true to let the session continue. Return false to refuse the peer: a\n * Logout carrying a Text reason is sent and the transport is dropped, so onReady\n * is never reached and no heartbeat is started.\n *\n * The verdict may be returned as a promise, for applications that must check the\n * credentials against an async source such as an http api or a database. While\n * that promise is pending the transport is paused and any message the peer sends\n * is queued, then replayed in order once the verdict arrives.\n *\n * @param view the login message\n * @param user extracted user from message\n * @param password extracted password from the message.\n * @protected\n */\n protected abstract onLogon (view: MsgView, user: string, password: string): boolean | Promise<boolean>\n}\n"]}
@@ -12,8 +12,13 @@ export declare class RecoveringTcpInitiator extends FixEntity {
12
12
  private initiator;
13
13
  private transport;
14
14
  private th;
15
+ private stopRequested;
16
+ static readonly DefaultRecoveryAttemptSecs = 5;
17
+ static readonly DefaultBackoffFailConnectSecs = 30;
18
+ static readonly DefaultConnectTimeoutSecs = 60;
15
19
  recoveryAttemptSecs: number;
16
20
  backoffFailConnectSecs: number;
21
+ connectTimeoutSecs: number;
17
22
  constructor(jsFixConfig: IJsFixConfig);
18
23
  private createSession;
19
24
  getState(): SessionState;
@@ -21,6 +26,7 @@ export declare class RecoveringTcpInitiator extends FixEntity {
21
26
  private resetSeq;
22
27
  private newTransport;
23
28
  private clearTimer;
29
+ stop(): void;
24
30
  private recover;
25
31
  start(): Promise<any>;
26
32
  run(initialTimeout?: number): Promise<any>;