Session Scheduler Sample Project
This sample demonstrates the usage of the Session Scheduler functionality.
Source code
using OnixS.Cme.ILink3;
using OnixS.Cme.ILink3.Testing;
using System;
using System.Globalization;
using System.Configuration;
using System.Threading;
using System.Threading.Tasks;
using OnixS.Cme.ILink3.Schedule;
namespace SessionSchedulerSample
{
internal static class SessionSchedulerSample
{
private static readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
private static Session CreateSession(SessionSettings settings, string segmentId, ulong uuid, string customKey)
{
Session session;
if (segmentId.ToUpper() == "CGW")
session = new CgwSession(settings, SessionStorageType.FileBasedStorage, uuid, customKey);
else
session = new Session(settings, int.Parse(segmentId, CultureInfo.InvariantCulture),
SessionStorageType.FileBasedStorage, uuid, customKey);
session.Warning += (sender, e) => Console.WriteLine($"WARNING: {e.Description}\n");
session.Error += (sender, e) => Console.WriteLine($"ERROR: {e.Description}\n"); ;
session.StateChanged += (sender, e) => Console.WriteLine("New session state: " + e.NewState);
return session;
}
private static (Session, Session) CreateSessionsPair(SessionSettings settings, string segmentId)
{
var primary = CreateSession(settings, segmentId, Session.UndefinedUuid, "primary");
primary.FaultToleranceIndicator = FaultToleranceIndicator.Primary;
var backup = CreateSession(settings, segmentId, primary.SessionId.Uuid, "backup");
backup.FaultToleranceIndicator = FaultToleranceIndicator.Backup;
backup.Failover += (object sender, FailoverEventArgs e) =>
{
backup.InSeqNum = primary.InSeqNum;
backup.OutSeqNum = primary.OutSeqNum;
primary.FaultToleranceIndicator = FaultToleranceIndicator.Backup;
};
return (primary, backup);
}
private static void FillSettings(SessionSettings settings, bool useEmulator)
{
settings.LicenseStore = "../../../../../license|../../../../license|.";
settings.TradingSystemVersion = "NC1.6";
settings.TradingSystemName = "Trading System";
settings.TradingSystemVendor = "OnixS";
if (useEmulator)
{
settings.SessionId = "XXX";
settings.FirmId = "001";
settings.AccessKey = "dGVzdHRlc3R0ZXN0dA==";
settings.SecretKey = "dGVzdHRlc3R0ZXN0dGVzdHRlc3R0";
settings.KeepAliveInterval = 5000;
settings.ReconnectAttempts = 0;
}
else
{
settings.SessionId = ConfigurationManager.AppSettings["SessionId"];
settings.FirmId = ConfigurationManager.AppSettings["FirmId"];
settings.AccessKey = ConfigurationManager.AppSettings["AccessKey"];
settings.SecretKey = ConfigurationManager.AppSettings["SecretKey"];
}
}
private static void Main(string[] args)
{
Console.WriteLine("CME iLink 3 SessionScheduler Sample.");
string marketSegmentId = "99";
string primaryHost = "127.0.0.1";
string backupHost = "127.0.0.1";
int pimaryPort = 41873;
int backupPort = pimaryPort + 1;
int logonDelaySeconds = 2;
int sessionDurationSeconds = 10;
bool useEmulator = false;
if (args.Length < 3)
{
useEmulator = true;
Console.WriteLine("Emulator is used, remote usage: [MarketSegmentId|'CGW'] [PrimaryHost] [BackupHost] [Port]");
}
else
{
marketSegmentId = args[0];
primaryHost = args[1];
pimaryPort = int.Parse(args[2], CultureInfo.InvariantCulture);
backupHost = args[3];
backupPort = int.Parse(args[4], CultureInfo.InvariantCulture);
}
try
{
var settings = new SessionSettings();
FillSettings(settings, useEmulator);
Task primaryEmulatorTask = null;
Gateway primaryEmulator = null;
Task backupEmulatorTask = null;
Gateway backupEmulator = null;
if (useEmulator)
{
primaryEmulator = new Gateway(pimaryPort, settings);
primaryEmulatorTask = Task.Run(() =>
{
primaryEmulator.AcceptSession(1, 1);
primaryEmulator.WaitUntilTerminate(
TimeSpan.FromMinutes(30), message => {});
});
backupEmulator = new Gateway(backupPort, settings);
backupEmulatorTask = Task.Run(() =>
{
backupEmulator.FaultToleranceIndicator = FaultToleranceIndicator.Backup;
backupEmulator.AcceptConnection(backupEmulator.SendReceiveTimeout);
backupEmulator.AcceptEstablish(1, 1);
backupEmulator.FaultToleranceIndicator = FaultToleranceIndicator.Primary;
backupEmulator.SendSequence(1);
bool stopRequested = false;
backupEmulator.WaitUntilTerminate(
TimeSpan.FromMinutes(30),
message => {},
message => backupEmulator.SendSequence(1), ref stopRequested);
});
}
var sessions = CreateSessionsPair(settings, marketSegmentId);
using (var scheduler = new SessionScheduler())
{
scheduler.ReconnectInterval = 1;
scheduler.SessionSchedulerError += (object sender, SessionSchedulerErrorEventArgs e) => Console.WriteLine($"WARNING: {e.Description}\n"); ;
scheduler.SessionSchedulerWarning += (object sender, SessionSchedulerWarningEventArgs e) => Console.WriteLine($"WARNING: {e.Description}\n"); ; ;
var primaryConnectivity = new SessionConnectionSettings(primaryHost, pimaryPort);
scheduler.Add(sessions.Item1, CreateSchedule(logonDelaySeconds, sessionDurationSeconds), primaryConnectivity);
var backupConnectivity = new SessionConnectionSettings(backupHost, backupPort);
scheduler.Add(sessions.Item2, CreateSchedule(logonDelaySeconds, sessionDurationSeconds), backupConnectivity);
Thread.Sleep(TimeSpan.FromSeconds(logonDelaySeconds + sessionDurationSeconds + 1));
scheduler.Remove(sessions.Item1);
scheduler.Remove(sessions.Item2);
}
Console.WriteLine("Done.");
if (useEmulator && primaryEmulatorTask != null)
{
if(primaryEmulatorTask.Wait(TimeSpan.FromMinutes(1)) && primaryEmulator != null)
primaryEmulator.Dispose();
}
if (useEmulator && backupEmulatorTask != null)
{
if(backupEmulatorTask.Wait(TimeSpan.FromMinutes(1)) && backupEmulator != null)
backupEmulator.Dispose();
}
}
catch (Exception ex)
{
Console.WriteLine("Exception: " + ex.ToString());
logger.Error("Exception: " + ex.ToString());
WaitForEnterKey("Press Enter to exit...");
}
NLog.LogManager.Shutdown();
}
private static SessionSchedule CreateSchedule(int logonDelaySeconds, int sessionDurationSeconds)
{
var now = DateTime.UtcNow;
var dayOfWeek = now.DayOfWeek;
var nowTime = now.TimeOfDay;
var logonTime = nowTime + TimeSpan.FromSeconds(logonDelaySeconds);
var logoutTime = logonTime + TimeSpan.FromSeconds(sessionDurationSeconds);
return new SessionSchedule(dayOfWeek, dayOfWeek, logonTime, logoutTime);
}
private static void WaitForEnterKey(string message)
{
Console.WriteLine(message);
if (Console.IsInputRedirected)
Console.In.Read();
else
Console.ReadKey();
}
}
}