• Version 1.7.1
Show / Hide Table of Contents

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();
        }
    }
}

In this article
Back to top Copyright © Onix Solutions.
Generated by DocFX