/// <summary>
        /// The HandleRxMessage method is invoked by the owner of an
        /// instance of a session to inform it that data has arrived
        /// from the peer system.
        /// </summary>
        /// <param name="mb">
        /// The message block that contains the data received from
        /// the peer system the session is communicating with.
        /// </param>
        public void HandleRxMessage(VfxEngine.Ipc.VfxMsgBlock mb)
        {
            string             content = Encoding.ASCII.GetString(mb.Buffer, 0, mb.Length());
            VfxFixParserResult fpr     = _fixParser.Parse(content, null, null, null);

            while (fpr.Status == VfxFixParserStatus.MsgComplete)
            {
                // REC: Adjust the read index in the message block
                // to compensate for the number of bytes parsed from
                // the incoming data stream:
                mb.RdIndex += fpr.Consumed;
                // REC: Crunch the message block to remove the data
                // that has already been parsed:
                mb.Crunch();

                // REC: Reset the timestamp that is used to determine
                // when the last message was received from the peer:
                this._lastRxTicks = DateTime.Now.Ticks;

                // REC: Determine if the message is a session layer
                // message and process it accordingly:
                FixField fldMsgType = fpr.Message.Header.GetField(35);
                if (fldMsgType != null)
                {
                    string strMsgType = fldMsgType.Content;
                    if (!string.IsNullOrEmpty(strMsgType))
                    {
                        switch (strMsgType)
                        {
                        case "A":
                            // Received a FIX logon message:
                            HandleSession_Logon(fpr.Message);
                            break;

                        case "0":
                            // Received a FIX heartbeat message:
                            HandleSession_Heartbeat(fpr.Message);
                            break;

                        case "1":
                            // Received a FIX test request:
                            HandleSession_TestRequest(fpr.Message);
                            break;

                        case "2":
                            // Received a FIX resend request:
                            HandleSession_Resend(fpr.Message);
                            break;

                        case "5":
                            // Received a FIX logout message:
                            HandleSession_Logout(fpr.Message);
                            break;

                        default:
                            // Received a message that should be
                            // routed to the session's owner:
                            HandleSession_Message(fpr.Message);
                            break;
                        }
                    }
                    else
                    {
                        // REC: If the session's identity hasn't been
                        // established yet, just throw an exception and
                        // let the session's owner shut it down:
                        if (_currentState == SessionStates.Session_Pending)
                        {
                            throw new ArgumentException("Initial message missing required field - FIX MsgType.");
                        }
                        else
                        {
                            // REC: The session has been established, so the
                            // session can send a reject message:
                        }
                    }
                }
                else
                {
                }

                // REC: Attempt to parse another message from
                // the buffer of data that has been received:
                content = Encoding.ASCII.GetString(mb.Buffer, 0, mb.Length());
                fpr     = _fixParser.Parse(content, null, null, null);
            }

            // REC: If the parser couldn't extract a complete message
            // from the supplied buffer, determine what to do next:
            if (fpr.Status != VfxFixParserStatus.MsgComplete)
            {
            }
        }
Exemple #2
0
        /// <summary>
        /// The HandleReceive_Entrypoint method is the entrypoint for
        /// the buffering thread that is started by the module if the
        /// module's owner has enabled incoming IO buffering.
        /// </summary>
        /// <param name="context"></param>
        private void HandleReceive_Entrypoint(object context)
        {
            // REC: The fragment buffer is used when there is residual
            // data remaining from a previously processed buffer. This
            // is allocated at 2x the receive block size, in order for
            // reducing the need to "expand" the fragment buffer when
            // data is left over from a receive operation:
            VfxMsgBlock rxFragment = new VfxMsgBlock(16384);

            while (true)
            {
                // REC: Lock the pending receive queue and check whether or not
                // there are any receive blocks waiting to be processed:
                IoContext rxPending = null;
                lock (this._synchRxPendingQueue)
                {
                    if (this._rxPendingQueue.Count > 0)
                    {
                        rxPending = this._rxPendingQueue.Dequeue();
                    }
                }

                if (rxPending != null)
                {
                    // REC: If there is data in the fragment buffer
                    // then we need to append the data from the incoming
                    // receive context to it:
                    if (rxFragment.Length() > 0)
                    {
                        rxFragment.Append(rxPending._ipcBuffer);

                        // REC: Dispatch from the fragment buffer instead
                        // of from the receive context:
                        EventHandler <VfxIpcEventArgs> tmp = EventDispatch;
                        if (tmp != null)
                        {
                            tmp(this, new VfxIpcEventArgs(rxFragment));
                            rxFragment.Crunch();
                        }

                        // REC: Reset the pointers in the receive context
                        // since its data has been copied to the fragment
                        // buffer for subsequent processing:
                        rxPending._ipcBuffer.RdIndex = rxPending._ipcBuffer.WrIndex = 0;
                    }
                    else
                    {
                        // REC: There is no fragment remaining from the previous
                        // receive operation, so we can just dispatch directly from
                        // the received context:
                        EventHandler <VfxIpcEventArgs> tmp = EventDispatch;
                        if (tmp != null)
                        {
                            tmp(this, new VfxIpcEventArgs(rxPending._ipcBuffer));
                            rxPending._ipcBuffer.Crunch();
                        }

                        // REC: Determine if there is a fragment in the buffer
                        // so that we can chain it to subsequent blocks:
                        if (rxPending._ipcBuffer.Length() > 0)
                        {
                            // REC: There is a fragment of a message remaining
                            // in the current buffer, so it has to be copied into
                            // the fragment buffer for further processing:
                            rxFragment.Append(rxPending._ipcBuffer);

                            // REC: Reset the points in the pending receive context
                            // since it has been copied into the fragment buffer:
                            rxPending._ipcBuffer.RdIndex = 0;
                            rxPending._ipcBuffer.WrIndex = 0;
                        }
                    }

                    // REC: Put the receive context back into the queue so
                    // that it can be used by subsequent receive operations:
                    lock (this._rxContextQueue)
                    {
                        this._rxContextQueue.Enqueue(rxPending);
                    }
                }
                else
                {
                    // REC: A message block wasn't available for us on this
                    // iteration, so just wait until one is added to the queue:
                    this._eventRxBuffer.WaitOne();
                }
            }
        }