OnixS C++ B3 BOE Binary Order Entry  1.2.0
API Documentation
TCPDirect Getting Started Sample

This sample shows how to connect TCPDirect session to the pre-defined host and port.

When the session is established, the NewOrderSngle message is sent to the counterparty.

Using TCPDirect Network Stack

TCPDirect is part of Solarflare’s suite of network acceleration technologies.

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).

For developing/debugging purposes, the OnixS B3 BOE SDK provides TCPDirect emulation for Windows over usual sockets, so the TCPDirect Getting Started sample can be run in loopback mode under Windows.

Source code

#include "../Common/Helpers.h"
#include "../Common/Listener.h"
#include "../Settings/Defaults.h"
using namespace Samples;
using namespace Threading;
SecurityID securityId;
Int64 priceMantissa;
MarketSegmentID marketSegmentId;
int main(int argc, char * argv[]) {
clog << "B3 BOE TCPDirect Getting Started Sample." << endl << endl;
marketSegmentId = DefaultMarketSegmentId;
// Use the IP address belonging to the TcpDirectStack interface in emulator mode.
string host = "192.168.0.1";
Port port = 62000;
bool useEmulator = false;
if(argc < 4) {
#if defined(ONIXS_B3_BOE_HAS_GATEWAY_EMULATOR)
useEmulator = true;
#else
std::cerr << "usage: [MarketSegmentId] [Host] [Port] (SecurityId) (PriceMantissa)" << std::endl;
return 1;
#endif
}
else {
marketSegmentId = atoi(argv[1]);
host = argv[2];
port = atoi(argv[3]);
}
securityId = argc > 4 ? fromStr<SecurityID>(argv[4]) : DefaultSecurityId;
priceMantissa = argc > 5 ? fromStr<Int64>(argv[5]) : DefaultPriceMantissa;
#if defined(ONIXS_B3_BOE_HAS_GATEWAY_EMULATOR)
std::unique_ptr<GatewayEmulatorThread> gateway;
#endif
int result = 0;
try {
SignalHelper::manageLinuxSignals();
const SessionSettings settings = fillSettings(useEmulator);
#if defined(ONIXS_B3_BOE_HAS_GATEWAY_EMULATOR)
if(useEmulator)
gateway.reset(new GatewayEmulatorThread(settings.licenseStores(), host, port));
#endif
TcpDirectAttr attr;
// The default interface name could be provided by the environment variable
// ZF_ATTR="interface=<interface-name>", see TCPDirect specs,
//
// or could be set manually:
// attr.set("interface", "interface-name");
TcpDirectStack tcpDirectStack(attr);
bool finished = false;
class TcpDirectListener : public Listener
{
public:
explicit TcpDirectListener(bool & finished)
: finished_(finished) {}
void onStateChange(SessionStateId::Enum newState, SessionStateId::Enum prevState, Session * session) ONIXS_B3_BOE_OVERRIDE
{
Listener::onStateChange(newState, prevState, session);
switch(newState) {
case SessionStateId::Established:
{
NewOrderSingle order;
Helper::setOrderFields(order, marketSegmentId, securityId, DefaultAccount, priceMantissa);
// The TCPDirect technology is NOT thread-safe.
// Therefore, the event dispatching and message sending should be performed from the same thread.
session->send(order);
clog << "\nThe order was sent." << endl;
break;
}
case SessionStateId::Disconnected:
finished_ = true;
break;
default:
break;
}
}
void onError(
SessionErrorReason::Enum reason, const std::string & text, Session * session, Messaging::SbeMessage msg) ONIXS_B3_BOE_OVERRIDE
{
Listener::onError(reason, text, session, msg);
finished_ = true;
}
private:
bool & finished_;
}
listener(finished);
Session session(tcpDirectStack, settings, &listener);
session.connectAsync(host, port);
while(!finished)
{
// The TCPDirect technology is NOT thread-safe.
// Therefore, the event dispatching and message sending should be performed from the same thread.
tcpDirectStack.dispatchEvents();
if(Helper::keyPressed())
break;
}
session.disconnectAsync();
while(!tcpDirectStack.isQuiescent())
tcpDirectStack.dispatchEvents();
}
catch(const std::exception & ex) {
cerr << "\nEXCEPTION: " << ex.what() << endl;
result = 1;
}
#if defined(ONIXS_B3_BOE_HAS_GATEWAY_EMULATOR)
if(gateway) {
try {
gateway->wait();
}
catch(...) {
// Emulator exception (if any) is already reported from Emulator's thread
}
}
#endif
return result;
}