Esempio n. 1
0
        /// <summary>
        /// The HandleTx method is invoked to request that an instance
        /// of the VfxTcpModule send the data in the specified message
        /// block out to the peer system it is connected to.
        /// </summary>
        /// <param name="mb">
        /// The message block that contains the data that is to be sent
        /// to the peer system the module is connected to.
        /// </param>
        public void HandleTx(VfxMsgBlock mb)
        {
            if (_moduleState == ModuleStates.Module_State_Active)
            {
                // REC: Send all of the data in the buffer:
                while (mb.Length() > 0)
                {
                    IoContext ctx = null;
                    lock (_synchIoContextQueue)
                    {
                        if (_ioContextQueue.Count > 0)
                        {
                            ctx = _ioContextQueue.Dequeue();
                        }
                    }

                    if (ctx != null)
                    {
                        if (ctx._ipcBuffer.Remaining() >= mb.Length())
                        {
                            // REC: Append the contents of the buffer
                            // to the IO context's buffer and push it
                            // onto the outgoing queue:
                            ctx._ipcBuffer.UnsafeAppend(mb);
                            mb.RdIndex = mb.WrIndex;

                            InitiateSend(ctx, false);
                        }
                        else
                        {
                            // REC: Copy as much data as possible into
                            // the context and attempt to send that:
                            int txLength = ctx._ipcBuffer.Remaining();
                            ctx._ipcBuffer.UnsafeAppend(mb, txLength);

                            // REC: Adjust the source buffer's index:
                            mb.RdIndex += txLength;

                            InitiateSend(ctx, false);
                        }
                    }
                    else
                    {
                        // REC: Wait for a buffer to become available:
                        _eventTxBuffer.WaitOne();
                    }
                }
            }
        }
Esempio n. 2
0
        /// <summary>
        /// The UnsafeAppend method is invoked to conduct an unsafe
        /// copy of the data in an outside message block into the buffer
        /// that is being managed by this instance.
        /// </summary>
        /// <param name="src">
        /// The source of the data that is to be copied into the current
        /// message block instance.
        /// </param>
        /// <param name="len">
        /// The length of the data that is to be copied from the outside
        /// message block into this one's buffer.
        /// </param>
        unsafe public void UnsafeAppend(VfxMsgBlock src, int len)
        {
            fixed(byte *pDst = &_buffer[WrIndex])
            {
                fixed(byte *pSrc = &src._buffer[src.RdIndex])
                {
                    for (int i = 0; i != len; i++)
                    {
                        pDst[i] = pSrc[i];
                    }
                }
            }

            WrIndex += src.Length();
        }
Esempio n. 3
0
        /// <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)
            {
            }
        }
Esempio n. 4
0
 /// <summary>
 /// The Append method is invoked to append the content of an
 /// message block to the content of the current instance.
 /// </summary>
 /// <param name="src">
 /// The message block that contains the data which is to be
 /// copied into the message block's buffer.
 /// </param>
 public void Append(VfxMsgBlock src)
 {
     System.Array.Copy(src.Buffer, src.RdIndex, _buffer, WrIndex, src.Length());
     WrIndex += src.Length();
 }
Esempio n. 5
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();
                }
            }
        }
Esempio n. 6
0
 public IoContext(Socket socket, VfxMsgBlock buffer)
 {
     _ipcSocket = socket;
     _ipcBuffer = buffer;
 }
Esempio n. 7
0
 /// <summary>
 /// Initializes an instance of VfxIpcEventArgs with a specific
 /// message block that contains data that has been received from
 /// the peer system associated with an IPC module.
 /// </summary>
 /// <param name="token">
 /// The unique token associated with the event.
 /// </param>
 /// <param name="msgBlock">
 /// The message block that contains the data.
 /// </param>
 public VfxIpcEventArgs(string token, VfxMsgBlock msgBlock)
 {
     _eventType = VfxIpcEventTypes.Event_Session_Message;
     _eventData = msgBlock;
     _token     = token;
 }
Esempio n. 8
0
 /// <summary>
 /// Initializes an instance of VfxIpcEventArgs with a specific
 /// message block that contains data that has been received from
 /// the peer system associated with an IPC module.
 /// </summary>
 /// <param name="msgBlock">
 /// The message block that contains the data.
 /// </param>
 public VfxIpcEventArgs(VfxMsgBlock msgBlock)
 {
     _eventType = VfxIpcEventTypes.Event_Session_Message;
     _eventData = msgBlock;
 }