Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

not able to capture the return message after login and seq mismatch #810

Open
thisisMehere opened this issue Nov 24, 2023 · 2 comments
Open

Comments

@thisisMehere
Copy link

I am having trouble trying to capture the logout message.

For example, after I click the button to logout with this function

   private void DisconnectFromServer()
        {
            app.DisconnectSession();
              initiator.Stop();
            initiator = null;
            isConnected = false;
            connectionTimer.Stop();
            connectionStatusLabel.Text = "Disconnected";
            connectionStatusLabel.BackColor = Color.HotPink;
        }
        public void DisconnectSession()
        {
            try
            {
                if (_session != null && _session.IsLoggedOn)
                {
                    _session.Disconnect("Disconnecting session");
                    Console.WriteLine("Session disconnected.");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }

  1. the session would disconnect without problem, but i can only see the message i SENT out to the server, but not able to receive the confirmation Logout message from the server.
  2. when i try to connect to a session which is already connected from someone else, i cannot get the return error message, i can only see the SENT message to the server. (PS, i can see the return message from the log file, but i am not able to populate it in my program).
  3. when there is a seq mismatch, i cannot see the error message like 2. Also, I am not able to customize a seq number to resend.
    the following is my code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using QuickFix;
using QuickFix.Fields;
using System.Windows.Forms;
using Message = QuickFix.Message;

namespace A
{
    class MyQuickFixApp : MessageCracker, IApplication
    {
        private Label connectionStatusLabel;
        private DataGridView dataGridView;
        private Session _session;
        private SessionScreen sessionScreen; // Add a reference to the MessageScreen instance
        private char defaultDelim;
        private SessionID _sessionID;
        static readonly decimal DEFAULT_MARKET_PRICE = 10;

        int orderID = 0;
        int execID = 0;

        private string GenOrderID() { return (++orderID).ToString(); }
        private string GenExecID() { return (++execID).ToString(); }

        public MyQuickFixApp(DataGridView dataGridView, Label connectionStatusLabel, SessionScreen sessionScreen, char defaultDelim, SessionID sessionID)
        {
            this.dataGridView = dataGridView;
            this.connectionStatusLabel = connectionStatusLabel;
            this.sessionScreen = sessionScreen;
            this.defaultDelim = defaultDelim;
            this._sessionID = sessionID;
        }

        public void FromApp(Message message, SessionID sessionID)
        {
            try
            {
                    Crack(message, sessionID);
                    Console.WriteLine("OUT: " + message);
                    UpdateDataGridView(message.ToString()); 
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

        }

        private void UpdateConnectionStatusLabel(string status)
        {
            try
            {
                connectionStatusLabel.Invoke((MethodInvoker)delegate
                {
                    connectionStatusLabel.Text = status;
                });
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }

        public void ToApp(Message message, SessionID sessionID)
        {
            try
            {
                UpdateDataGridView(message.ToString());

                Console.WriteLine("out message: " + message);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
        public void OnCreate(SessionID sessionID)
        {
            try
            {
                Session existingSession = Session.LookupSession(sessionID);
                if (existingSession != null && existingSession.IsLoggedOn)
                {
                    // Handle the case where there is already an existing connection
                    Console.WriteLine("Existing connection found: " + sessionID);
                    existingSession.Logout("Another connection already exists");
                    return; // Exit the method or perform any necessary actions
                }

                _session = Session.LookupSession(sessionID);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
        public void OnLogout(SessionID sessionID)
        {
            try
            {
                Console.WriteLine("Session disconnected: " + sessionID + " ____ " );
                sessionScreen.UpdateConnectionStatus("Connection dropped by the server.", Color.HotPink);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
        public void OnLogon(SessionID sessionID)
        {
            Console.WriteLine("Session connected: " + sessionID);
        }
        public void DisconnectSession()
        {
            try
            {
                if (_session != null && _session.IsLoggedOn)
                {
                    _session.Disconnect("Disconnecting session");
                    Console.WriteLine("Session disconnected.");

                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);

            }
        }
        //sending to source
        public void FromAdmin(Message message, SessionID sessionID)
        {
            try
            {
                  Crack(message, sessionID);
                Console.WriteLine("Admin: " + message);
                UpdateDataGridView(message.ToString());
                if (message.Header.GetString(Tags.MsgType) == MsgType.LOGON)
                {
                    // Check if the logon was successful
                    if (message.IsSetField(Tags.EncryptMethod) && message.IsSetField(Tags.HeartBtInt))
                    {
                        // Logon successful
                        Console.WriteLine("Logon successful");

                        // Update the label color in the SessionScreen class
                        sessionScreen.UpdateConnectionStatus("Connected", Color.LimeGreen);
                    }
                    else
                    {
                        // Logon failed
                        Console.WriteLine("Logon failed");

                        // Update the label color in the SessionScreen class
                        sessionScreen.UpdateConnectionStatus("Logon Failed", Color.Red);
                    }
                }
                else if (message.Header.GetString(Tags.MsgType) == MsgType.LOGOUT)
                {
                    Console.WriteLine("xx");
                }
                sessionScreen.OnMessageArrived();

            }
            catch (Exception ex)
            {
                Console.WriteLine("failed to login: " + ex.Message);
            }
        }
        public void Send(QuickFix.Message m)
        {
            try
            {
                QuickFix.Session.SendToTarget(m, _sessionID);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        // sending to Target
        public void ToAdmin(Message message, SessionID sessionID)
        {
            try
            {
                Console.WriteLine("OUT: " + message);
                UpdateDataGridView(message.ToString());
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }

        //update the datagridview when new message recevied or sent 
        private void UpdateDataGridView(string message)
        {
            try
            {
            //it will display the message to datagrid 
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        public void SendMessage(string message)
        {
            try
            {
                QuickFix.Message fixMessage = new QuickFix.Message(message);
                if (_session != null)
                    _session.Send(fixMessage);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
        private bool IsIncomingMessage(QuickFix.Message message)
        {
            try
            {
                // Get the SessionID of the current application instance
                SessionID currentSessionID = _session.SessionID;

                // Get the SessionID of the message
                // Get the BeginString, SenderCompID, and TargetCompID fields from the message header
                string beginString = message.Header.GetString(Tags.BeginString);
                string senderCompID = message.Header.GetString(Tags.SenderCompID);
                string targetCompID = message.Header.GetString(Tags.TargetCompID);

                // Create a SessionID object for the message
                SessionID messageSessionID = new SessionID(beginString, senderCompID, targetCompID);

                // Compare the SessionIDs to determine the message direction
                return !messageSessionID.Equals(currentSessionID);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return false;

            }
        }

        public void OnMessage(QuickFix.FIX42.NewOrderSingle n, SessionID s)
        {
            Symbol symbol = n.Symbol;
            Side side = n.Side;
            OrdType ordType = n.OrdType;
            OrderQty orderQty = n.OrderQty;
            ClOrdID clOrdID = n.ClOrdID;
            Price price = new Price(DEFAULT_MARKET_PRICE);

            switch (ordType.getValue())
            {
                case OrdType.LIMIT:
                    price = n.Price;
                    if (price.Obj == 0)
                        throw new IncorrectTagValue(price.Tag);
                    break;
                case OrdType.MARKET: break;
                default: throw new IncorrectTagValue(ordType.Tag);
            }

            QuickFix.FIX42.ExecutionReport exReport = new QuickFix.FIX42.ExecutionReport(
                new OrderID(GenOrderID()),
                new ExecID(GenExecID()),
                new ExecTransType(ExecTransType.NEW),
                new ExecType(ExecType.FILL),
                new OrdStatus(OrdStatus.FILLED),
                symbol,
                side,
                new LeavesQty(0),
                new CumQty(orderQty.getValue()),
                new AvgPx(price.getValue()));

            exReport.Set(clOrdID);
            exReport.Set(orderQty);
            exReport.Set(new LastShares(orderQty.getValue()));
            exReport.Set(new LastPx(price.getValue()));

            if (n.IsSetAccount())
                exReport.SetField(n.Account);

            try
            {
                Session.SendToTarget(exReport, s);
            }
            catch (SessionNotFound ex)
            {
                Console.WriteLine("==session not found exception!==");
                Console.WriteLine(ex.ToString());
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }

        public void OnMessage(QuickFix.FIX42.OrderCancelReplaceRequest msg, SessionID s)
        {
            string orderid = (msg.IsSetOrderID()) ? msg.OrderID.Obj : "unknown orderID";
            QuickFix.FIX42.OrderCancelReject ocj = new QuickFix.FIX42.OrderCancelReject(
                new OrderID(orderid), msg.ClOrdID, msg.OrigClOrdID, new OrdStatus(OrdStatus.REJECTED), new CxlRejResponseTo(CxlRejResponseTo.ORDER_CANCEL_REPLACE_REQUEST));
            ocj.CxlRejReason = new CxlRejReason(CxlRejReason.UNKNOWN_ORDER);
            ocj.Text = new Text("Executor does not support order cancel/replaces");

            try
            {
                Session.SendToTarget(ocj, s);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }


        #endregion //MessageCracker overloads
    }
}
@gbirchmeier
Copy link
Member

This is a legit issue I think. I'm not sure when I can dig into it, but I would start by creating a small client app and using Examples/SimpleAcceptor as a counterparty. I'm trying to close out some other PRs this week, but I hope to come back to this.

Also, I am not able to customize a seq number to resend.

This is not something a user app should be doing. If the seq nums get out of whack, one side should request a reset.

@gbirchmeier
Copy link
Member

I think bullet 1 is basically #856, which I'm experiencing myself right now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants