Memory-based session storage is typically used to maintain a high-performance FIX session when persisting of a sessions state and messages to the file system is not required. This sample demonstrates how to use pluggable session storage.
#include <map>
{
public:
MySessionStorage();
void clear() override;
void close(bool keepSequenceNumbers, bool doBackup) override;
void storeInbound(
const OnixS::FIX::Message & message,
OnixS::FIX::SequenceNumber messageSequenceNumber,
const OnixS::FIX::ISessionStorage::RawMessagePointer& pointer,
bool logMessage)
override;
void storeInbound(
const OnixS::FIX::FlatMessage & message,
OnixS::FIX::SequenceNumber messageSequenceNumber,
const OnixS::FIX::ISessionStorage::RawMessagePointer & pointer,
bool logMessage)
override;
using RawMessage = std::vector<char>;
using MessageSequenceNumber2RawMessage = std::map<OnixS::FIX::SequenceNumber, RawMessage>;
MessageSequenceNumber2RawMessage outgoingMessages_;
void storeOutbound(const OnixS::FIX::Message &, const OnixS::FIX::ISessionStorage::RawMessagePointer & pointer, bool logMessage) override;
void storeOutbound(
const OnixS::FIX::FlatMessage &,
OnixS::FIX::SequenceNumber sequenceNumber,
const OnixS::FIX::ISessionStorage::RawMessagePointer & pointer,
bool logMessage)
override;
void setSessionTerminationFlag(bool terminated) override;
void sessionCreationTime(OnixS::FIX::Timestamp) override;
OnixS::FIX::Timestamp sessionCreationTime() override;
void flush() override {}
size_t resendingQueueSize() const override { return 1000; };
void resendingQueueSize(size_t) override {}
private:
bool isSessionTerminated_;
OnixS::FIX::Timestamp sessionCreationTime_;
};
#include "MySessionStorage.h"
#include <iostream>
#include <string>
MySessionStorage::MySessionStorage()
: isSessionTerminated_(false),
inSeqNum_(0),
outSeqNum_(0)
{}
void MySessionStorage::clear()
{
std::clog << "Clear the session storage." << std::endl;
inSeqNum_ = 0;
outSeqNum_ = 0;
outgoingMessages_.clear();
}
void MySessionStorage::close(bool keepSequenceNumbers, bool doBackup)
{
if(doBackup)
{
std::clog << "Back up the stored data." << std::endl;
}
if(!keepSequenceNumbers)
clear();
}
void MySessionStorage::getOutbound(
SequenceNumber beginSequenceNumber,
SequenceNumber endSequenceNumber, ISessionStorageListener * listener)
{
std::clog << "getOutbound(" << beginSequenceNumber << ", " << endSequenceNumber << ",..)" << std::endl;
for(
SequenceNumber i = beginSequenceNumber; i <= endSequenceNumber; ++i)
{
const auto it = outgoingMessages_.find(i);
if(it != outgoingMessages_.end())
}
}
{
return inSeqNum_;
}
{
std::clog << "inSeqNum(" << messageSequenceNumber << ")" << std::endl;
inSeqNum_ = messageSequenceNumber;
}
void MySessionStorage::storeInbound(
const Message &,
SequenceNumber messageSequenceNumber,
const RawMessagePointer& pointer,
bool logMessage)
{
inSeqNum_ = messageSequenceNumber;
if (logMessage)
{
std::clog << "storeInbound(" << messageSequenceNumber << ", " << std::string(
reinterpret_cast<const char*>(pointer.buffer_), pointer.length_)
<< ')' << std::endl;
}
}
void MySessionStorage::storeInbound(
const FlatMessage &,
SequenceNumber messageSequenceNumber,
const RawMessagePointer & pointer,
bool logMessage)
{
inSeqNum_ = messageSequenceNumber;
if(logMessage)
{
std::clog << "storeInbound(" << messageSequenceNumber << ", " << std::string(
reinterpret_cast<const char*>(pointer.buffer_), pointer.length_)
<< ')' << std::endl;
}
}
void MySessionStorage::storeOutbound(
const Message & message,
const RawMessagePointer & pointer,
bool logMessage)
{
outSeqNum_ = messageSequenceNumber;
if(logMessage)
{
std::clog << "storeOutbound(" << messageSequenceNumber << ", " << std::string(
reinterpret_cast<const char*>(pointer.buffer_), pointer.length_)
<< ')' << std::endl;
outgoingMessages_.insert(make_pair(messageSequenceNumber,
RawMessage(pointer.buffer_,
pointer.buffer_ + pointer.length_)));
}
}
void MySessionStorage::storeOutbound(
const FlatMessage &,
SequenceNumber sequenceNumber,
const RawMessagePointer & pointer,
bool logMessage)
{
outSeqNum_ = sequenceNumber;
if(logMessage)
{
std::clog << "storeOutbound(" << sequenceNumber << ", " << std::string(
reinterpret_cast<const char*>(pointer.buffer_), pointer.length_)
<< ')' << std::endl;
outgoingMessages_.insert(make_pair(sequenceNumber,
RawMessage(pointer.buffer_,
pointer.buffer_ + pointer.length_)));
}
}
void MySessionStorage::setSessionTerminationFlag(bool terminated)
{
std::clog << "setSessionTerminationFlag(" << terminated << ")" << std::endl;
isSessionTerminated_ = terminated;
}
{
return outSeqNum_;
}
void MySessionStorage::outSeqNum(
SequenceNumber messageSequenceNumber)
{
std::clog << "outSeqNum(" << messageSequenceNumber << ")" << std::endl;
outSeqNum_ = messageSequenceNumber;
}
void MySessionStorage::sessionCreationTime(
Timestamp timestamp)
{
std::clog <<
"sessionCreationTime(" << timestamp.
toString() <<
")" << std::endl;
sessionCreationTime_ = timestamp;
}
Timestamp MySessionStorage::sessionCreationTime()
{
return sessionCreationTime_;
}
#include "MySessionStorage.h"
#include "../../Common/Helpers.h"
#include "../../Common/Settings.h"
using namespace Settings;
using namespace OnixS::FIX::FIX44;
namespace {
{
public:
void onInboundApplicationMsg(Message &, Session *) override {}
};
};
int main()
{
try {
EngineShutdownGuard engineShutdownGuard;
MySessionListener listener;
MySessionStorage storage;
Message order(Values::MsgType::NewOrderSingle, FixProtocolVersion);
session.send(&order);
MessagePtr foundMessage(session.findSentMessage(1));
if(!foundMessage.get())
throw std::runtime_error("Stored message was not found.");
std::clog << std::endl << "Message found: " << *foundMessage << std::endl;
session.resetLocalSequenceNumbers();
}
catch(const std::exception & ex) {
processSampleException(ex.what());
return 1;
}
return 0;
}