This sample shows how to connect TCPDirect session to the pre-defined host and port.
The TCP loopback is not supported by TCPDirect technology, so the emulator should be started on a remote host (or on a different physically connected card with a configured route to it).
#include "../Settings/Defaults.h"
#include "../Common/Helpers.h"
#include "../Common/Listener.h"
#include "../Common/Settings.h"
#include "../Common/Signal.h"
#include "../Common/Emulator.h"
using namespace Samples;
using namespace Threading;
int main(int argc, char * argv[])
{
const AppConfiguration<
SettingsConfiguration
, ConnectivityConfiguration
, LogonConfiguration
, NetworkInterfaceConfiguration
, StorageConfiguration<SessionStorageType::FileBased>
> cfg{"TCPDirectGettingStarted", argc, argv};
try
{
SignalHelper::manageSignals();
auto settings = fillSettings(cfg);
const auto emulator = createEmulator(settings, cfg, true);
const auto bgwCredentials = receiveBgwCredentials(settings, cfg.host(), cfg.port());
class TcpDirectListener : public Listener
{
public:
explicit TcpDirectListener(const LogonConfiguration& cfg)
: traderLogonRequest_(Helper::createTraderLogonRequest(cfg.traderId(), cfg.traderPwd()))
, order_(Helper::createOrder(cfg.traderId()))
{
}
void onTraderLogonReport(const Messaging::TraderLogonReport msg, Session* session) override
{
Listener::onTraderLogonReport(msg, session);
try
{
traderLoggedOn.get_future().get();
}
catch(const std::exception& e)
{
onError(SessionErrorReason::UnsuccessfulLogonReportInReplyOnLogonRequest, e.what(), session, msg);
return;
}
session->send(order_);
}
void onStateChange(SessionStateId::Enum newState, SessionStateId::Enum prevState, Session * session) override
{
Listener::onStateChange(newState, prevState, session);
switch(newState)
{
case SessionStateId::Established:
{
session->send(traderLogonRequest_);
break;
}
case SessionStateId::Disconnected:
finished_ = true;
break;
default:
break;
}
}
void onError(
SessionErrorReason::Enum reason, const std::string & text, Session * session, Messaging::SbeMessage msg) override
{
Listener::onError(reason, text, session, msg);
finished_ = true;
}
bool finished() const noexcept {return finished_;}
private:
bool finished_ {false};
MessageHolder<TraderLogonRequest> traderLogonRequest_;
MessageHolder<NewOrderRequest> order_;
}
listener(cfg);
TcpDirectAttr attr;
attr.set("interface", cfg.nif());
TcpDirectStack stack{attr};
const auto bgwSession= createSession(stack, SessionType::BGW, settings, &listener, cfg.storage());
bgwSession->connectAsync(bgwCredentials.host, bgwCredentials.port);
std::clog << "\nPress <Ctrl+C> to disconnect the BGW session and terminate the application." << std::endl;
while(!listener.finished())
{
stack.dispatchEvents();
if(SignalHelper::interruptDetected())
break;
}
bgwSession->disconnectAsync();
while(!stack.isQuiescent())
stack.dispatchEvents();
}
catch(const std::exception & ex)
{
std::cerr << "\nEXCEPTION: " << ex.what() << std::endl;
return 1;
}
return 0;
}