fixparser-no-logging
Version:
FIX 5.0SP2 Parser
156 lines (138 loc) • 4.89 kB
text/typescript
/*
* fixparser
* https://gitlab.com/logotype/fixparser.git
*
* Copyright 2021 Victor Norgren
* Released under the MIT license
*/
import { EventEmitter } from 'events';
import * as EncryptMethod from './constants/ConstantsEncryptMethod';
import * as Fields from './constants/ConstantsField';
import * as HandlInst from './constants/ConstantsHandlInst';
import * as Messages from './constants/ConstantsMessage';
import * as OrderTypes from './constants/ConstantsOrderTypes';
import * as Side from './constants/ConstantsSide';
import * as TimeInForce from './constants/ConstantsTimeInForce';
import Field from './fields/Field';
import FIXParserBase from './FIXParserBase';
import Message from './message/Message';
import { timestamp } from './util/util';
export default class FIXParserBrowser extends EventEmitter {
public fixParserBase: FIXParserBase = new FIXParserBase();
public host: string | null = null;
public port: number | null = null;
public protocol: string | null = null;
public connectionString: string | null = null;
public socket: WebSocket | null = null;
public sender: string | null = null;
public target: string | null = null;
public messageSequence: number = 1;
public heartBeatInterval: number | undefined;
public heartBeatIntervalId: number | null = null;
public fixVersion: string = 'FIX.5.0SP2';
public stopHeartbeat() {
clearInterval(this.heartBeatIntervalId!);
}
public startHeartbeat() {
this.stopHeartbeat();
this.heartBeatIntervalId = setInterval(() => {
const heartBeat = this.createMessage(
new Field(Fields.MsgType, 0),
new Field(Fields.MsgSeqNum, this.getNextTargetMsgSeqNum()),
new Field(Fields.SenderCompID, this.sender),
new Field(Fields.SendingTime, this.getTimestamp()),
new Field(Fields.TargetCompID, this.target),
);
this.send(heartBeat);
}, this.heartBeatInterval);
}
public connect({
host = 'localhost',
port = 9878,
protocol = 'websocket',
sender = 'SENDER',
target = 'TARGET',
heartbeatIntervalMs = 60000,
fixVersion = this.fixVersion,
} = {}) {
this.host = host;
this.port = port;
this.protocol = protocol;
this.connectionString =
this.host.indexOf('ws://') === -1 &&
this.host.indexOf('wss://') === -1
? `ws://${this.host}:${this.port}`
: `${this.host}:${this.port}`;
this.sender = sender;
this.target = target;
this.heartBeatInterval = heartbeatIntervalMs;
this.fixVersion = fixVersion;
this.socket = new WebSocket(this.connectionString);
this.socket!.addEventListener('open', (event) => {
console.log(
`Connected: ${event}, readyState: ${this.socket!.readyState}`,
);
this.emit('open');
this.startHeartbeat();
});
this.socket!.addEventListener('close', (event) => {
console.log(
`Connection closed: ${event}, readyState: ${
this.socket!.readyState
}`,
);
this.emit('close');
this.stopHeartbeat();
});
this.socket!.addEventListener('message', (event) => {
const messages = this.fixParserBase.parse(event.data);
let i = 0;
for (i; i < messages.length; i++) {
this.emit('message', messages[i]);
}
});
}
public close() {
this.socket!.close();
}
public getNextTargetMsgSeqNum() {
return this.messageSequence;
}
public setNextTargetMsgSeqNum(nextMsgSeqNum: number) {
this.messageSequence = nextMsgSeqNum;
return this.messageSequence;
}
public getTimestamp(dateObject = new Date()) {
return timestamp(dateObject);
}
public createMessage(...fields: Field[]) {
return new Message(this.fixVersion, ...fields);
}
public parse(data: string) {
return this.fixParserBase.parse(data);
}
public send(message: Message) {
if (this.socket!.readyState === 1) {
this.setNextTargetMsgSeqNum(this.getNextTargetMsgSeqNum() + 1);
this.socket!.send(message.encode());
} else {
console.error(
'FIXParser: could not send message, socket not open',
message,
);
}
}
}
export { Field };
export { Fields };
export { Message };
export { Messages };
export { Side };
export { OrderTypes };
export { HandlInst };
export { TimeInForce };
export { EncryptMethod };
/**
* Export global to the window object.
*/
(global as any).FIXParser = FIXParserBrowser;