Engine initialisation is performed using the void Engine::FixEngine::init() method. This method must be called before any other API method. After using the Engine, call the void Engine::FixEngine::destroy() method to deallocate resources in use.
For example:
#include <iostream> #include <B2BITS_V12.h> using namespace std; int main(int argc, char* argv[]) { try { // initialization Engine::FixEngine::init(); // ... - main functionality // destruction Engine::FixEngine::destroy(); } catch(const Utils::Exception& ex) { cout << "EXCEPTION: " << ex.what() << endl; } return 0; }
For example:
FixEngine::singleton()->createSession(...)
To control acceptor session creation, create a class that is the Engine::SessionsManager class heir, and override the Engine::SessionsManager::onUnregisteredAcceptor() method in this class. If acceptor session is acceptable, the method must return "true". Otherwize, it must return "false".
Engine::FixEngine allows to register only one sessions manager for the FIX sessions. You may attach sessions manager object using Engine::FixEngine::registerSessionsManager() method.
For example:
class SsnManager : public Engine::SessionsManager{ public: virtual bool onUnregisteredAcceptor(Session* pSn, const FIXMessage& logonMsg) { clog << "Incoming logon: " << *logonMsg.toString() << endl; return true; } }; // The FixEngine initialization FixEngine::init("engine.properties"); // create and register SessionsManager SsnManager *g_mySM = new SsnManager(); FixEngine::singleton()->registerSessionsManager(g_mySM); ... // unregister and destroy SessionsManager FixEngine::singleton()->registerSessionsManager(NULL); delete g_mySM; // destruct FixEngine FixEngine::destroy();
Each session incapsulates message storage that is used to store sent and received messages. There are two storage types:
To process incoming messages, create a class that is the Engine::Application class heir, and override the Engine::Application::process() method. If the incoming message is successfully processed, the method must return "true", if the message cannot be processed at the moment, it must return "false".
If the Engine::Application::process() method does not return "true" (i.e. returns "false" or throws an exception), the session will try to deliver the first unprocessed message a specified number of times (DelayedProcessing.MaxDeliveryTries) in the interval, specified in the FIX Antenna configuration (DelayedProcessing.DeliveryTriesInterval). If the number of unsuccessful tries exceeds the MaxDeliveryTries, the Logout message with the "Application is not available" cause indication is sent to the counter-party.
It is also obliged to override the onLogonEvent, onLogoutEvent, onSequenceGapEvent, onSessionLevelRejectEvent and other methods. These are the call-back methods called to notify about the corresponding session-level events.
The Engine::Application::process() method is called only in the case of the delivery of incoming application-level message or a reject message. All other session-level messages are handled inside the FE.
If it is necessary to use the received application message outside the Engine::Application::process() method, use a clone of the original message (see the FIXMessage *EngineFIXMsgProcessor::clone(const Engine::FIXMessage &inMsg) const method).
For example:
class Appl : public Engine::Application{ public: virtual bool process(const FIXMessage & aMsg, const Engine::Session& aSn) { clog << "aMsg: " << *aMsg.toString() << endl; return true; } virtual void onLogonEvent(const LogonEvent* apEvent, const Session& aSn) { clog << "LogonEvent, the Logon message was received: " << apEvent->m_pLogonMsg->toString() << endl; } virtual void onLogoutEvent(const LogoutEvent* apEvent, const Session& aSn) { clog << "LogoutEvent, the Logout message was received: " << apEvent->m_pLogoutMsg->toString() << endl; } virtual void onSequenceGapEvent(const SequenceGapEvent* apEvent, const Session& aSn) { clog << "SequenceGapEvent" << endl; } virtual void onSessionLevelRejectEvent(const SessionLevelRejectEvent* apEvent, const Session& aSn) { clog << "SessionLevelRejectEvent" << endl; } virtual void onMsgRejectEvent(const MsgRejectEvent* event, const Session& sn){ clog << "MsgRejectEvent" << endl; } virtual void onResendRequestEvent(const ResendRequestEvent &,const Session &) { clog << "ResendRequestEvent" << endl; } virtual void onNewStateEvent(const NewStateEvent &,const Session &) { clog << "NewStateEvent" << endl; } virtual void onUnableToRouteMessage(const UnableToRouteMessageEvent &,const Session &) { clog << "UnableToRouteMessage" << endl; } virtual bool onResend(const FIXMessage &,const Session &) { clog << "Resend" << endl; return true; } virtual void onHeartbeatWithTestReqIDEvent(const HeartbeatWithTestReqIDEvent &,const Session &) { clog << "HeartbeatWithTestReqIDEvent" << endl; } };
If a pointer to the same Engine::Application is transmitted to several sessions, being established, it is recommended to make the Engine::Application::process() method synchronised.
Do not delete the registered Engine::Application until you unregister it.
The Engine::FIXMessage class is responsible for:
Repeating groups a usually addressed by leading tag.
To access fields inside repeating group it is required to get group instance first and then get fields value specifying entry number. Entries are enumerated starting from 0.
1.5.6