OnixS C++ FIX Engine  4.12.0
API Documentation
External Thread Sample

This sample connects to the pre-defined host and port (acts as a FIX Initiator). When the session is established, the SingleOrder - New FIX message is sent to the counterparty. This is done using the ExternalThread threading model.


Source code:


Listener.h:

class Listener : public OnixS::FIX::ISessionListener
{
public:
Listener() ONIXS_FIXENGINE_NOTHROW : finished_(false) {}
~Listener() ONIXS_FIXENGINE_OVERRIDE ONIXS_FIXENGINE_DEFAULT;
bool finished() const ONIXS_FIXENGINE_NOTHROW
{
return finished_;
}
/// Is called when the application-level message is received from the counterparty.
void onInboundApplicationMsg(Message & msg, Session * sn) ONIXS_FIXENGINE_FINAL;
/// Is called when the session-level message is received from the counterparty.
void onInboundSessionMsg(Message & msg, Session * sn) ONIXS_FIXENGINE_FINAL;
void onStateChange(SessionState::Enum newState, SessionState::Enum prevState, Session * sn) ONIXS_FIXENGINE_FINAL;
void onError(ErrorReason::Enum reason, const std::string & description, Session * sn) ONIXS_FIXENGINE_FINAL;
void onWarning(WarningReason::Enum reason, const std::string & description, Session * sn) ONIXS_FIXENGINE_FINAL;
private:
bool finished_;
};

Listener.cpp:

#include "Listener.h"
#include "../../Common/Helpers.h"
#include "../../Common/Settings.h"
using namespace Settings;
void Listener::onInboundApplicationMsg(Message & msg, Session *)
{
std::clog << "\nIncoming application-level message:\n" << msg << std::endl;
}
void Listener::onInboundSessionMsg(Message & msg, Session *)
{
std::clog << "\nIncoming session-level message:\n" << msg << std::endl;
}
void Listener::onStateChange(SessionState::Enum newState, SessionState::Enum prevState, Session *)
{
std::clog
<< "\nSession's state is changed, prevState="
<< SessionState::toString(prevState)
<< ", newState="
<< SessionState::toString(newState)
<< std::endl;
if(newState == SessionState::Disconnected)
finished_ = true;
}
void Listener::onError(ErrorReason::Enum, const std::string & description, Session *)
{
std::cerr << "\nSession-level error:" << description << std::endl;
finished_ = true;
}
void Listener::onWarning(WarningReason::Enum, const std::string & description, Session *)
{
std::cerr << "\nSession-level warning:" << description << std::endl;
}

ExternalThread.cpp:

#include "Listener.h"
#include "../../Common/Helpers.h"
#include "../../Common/Settings.h"
using namespace Settings;
int main()
{
std::clog << "ExternalThread sample." << std::endl << std::endl;
try
{
manageLinuxSignals();
EngineSettings settings;
settings.listenPort(ListenPort)
.licenseStore(LicenseStore);
TCPStandard::Stack stack;
Engine::init(settings, &stack);
Listener acceptorListener;
Session acceptor(&stack, TargetCompId, SenderCompId, FixProtocolVersion, &acceptorListener);
acceptor.logonAsAcceptor();
Listener initiatorListener;
Session initiator(&stack, SenderCompId, TargetCompId, FixProtocolVersion, &initiatorListener);
const bool SetResetSeqNumFlagOnLogon = true;
const int HeartBtInt = 30;
SecondSpan BigTimeout(HeartBtInt * 2);
{
TimeoutTimer timer(BigTimeout);
SharedFuture<void> logonTask = initiator.logonAsInitiatorAsync("localhost", ListenPort, HeartBtInt, ONIXS_FIXENGINE_NULLPTR, SetResetSeqNumFlagOnLogon);
while(!logonTask.isReady() && !timer.elapsed())
stack.dispatchEvents();
if(timer.elapsed())
{
std::clog << std::endl << "Cannot logon during the timeout." << std::endl;
initiator.breakConnection();
}
if(logonTask.hasException())
{
try
{
logonTask.get();
}
catch(const std::exception & ex)
{
std::clog << std::endl << "Logon fails with error: " << ex.what() << std::endl;
}
}
}
std::clog << "Press any key to send an order, disconnect the session and terminate the application." << std::endl;
while(!acceptorListener.finished() && !initiatorListener.finished() && !keyPressed())
stack.dispatchEvents();
Message order("D", FixProtocolVersion);
setOrderFields(&order);
initiator.send(&order);
{
TimeoutTimer timer(BigTimeout);
SharedFuture<void> logoutTask = initiator.logoutAsync("The session is disconnected");
while((!logoutTask.isReady() || !initiatorListener.finished()) && !timer.elapsed())
stack.dispatchEvents();
if(timer.elapsed())
{
std::clog << std::endl << "Cannot logout during the timeout." << std::endl;
initiator.breakConnection();
}
if(logoutTask.hasException())
{
try
{
logoutTask.get();
}
catch(const std::exception & ex)
{
std::clog << std::endl << "Logout fails with error: " << ex.what() << std::endl;
}
}
}
initiator.shutdown();
acceptor.shutdown();
Engine::shutdown();
while(!stack.isQuiescent())
stack.dispatchEvents();
}
catch(const std::exception & ex)
{
processSampleException(ex.what());
return 1;
}
return 0;
}