Пример #1
0
        /// <summary>
        /// The HandleIpcDispatch_EventOpened event handler is invoked in
        /// response to a new session being established between a peer
        /// system and the endpoint associated with the service.
        /// </summary>
        /// <param name="sender">
        /// The IPC endpoint that dispatched the event.
        /// </param>
        /// <param name="args">
        /// The details of the event being dispatched.
        /// </param>
        private void HandleIpcDispatch_EventOpened(object sender, VfxIpcEventArgs args)
        {
            // REC: Create a new instance of a FIX session to handle
            // the communication between the server and the peer:
            IVfxFixSession fixSession = null;

            // REC: Retrieve the version definition from the version
            // definition registry and determine what kind of session
            // needs to be created in order to handle the connection:
            IVfxFixVxRegistry vxRegistry = this._localServices.GetService(typeof(IVfxFixVxRegistry)) as IVfxFixVxRegistry;

            // REC: Check the version definition in order to tell if
            // this is a FIX 4.x or FIX 5.x service:
            VfxFixVxRecord vxRecord = vxRegistry.Get(this._sxVersion);
            if (vxRecord.Layer.ToLower().CompareTo("combined") == 0)
            {
                fixSession = new VfxFix4xServerSession();
            }
            else
            {
                fixSession = new VfxFix5xServerSession();
            }

            // REC: Initialize the session:
            fixSession.Init(_localServices, this);

            // REC: Create an entry for the session in the
            // local session map:
            _mapFixSessions.Add(fixSession.InstanceId, fixSession);

            // REC: Bind the FIX session to the IPC session:
            _mapFixToIpc.Add(fixSession.InstanceId, args.Token);
            // REC: Bind the IPC session to the FIX session:
            _mapIpcToFix.Add(args.Token, fixSession.InstanceId);

            // REC: Create the application session container
            // that will be passed to the app implementation
            // when events are generated on the session:
            VfxFixServerSession appSession = new VfxFixServerSession(fixSession);

            // REC: Create a binding between the FIX session
            // and the application session so that events from
            // the FIX session can be correlated to the correct
            // application session when events are dispatched to
            // the user's FIX application instance:
            _mapAppSessions.Add(fixSession.InstanceId, appSession);

            // REC: Inform the session that a peer system
            // has been connected to it:
            fixSession.HandleConnect();
        }
Пример #2
0
 /// <summary>
 /// The HandleDispatch event handler is invoked in response
 /// to an IPC event being dispatched to the session by the
 /// session's associated IPC module. The session assigns its
 /// unique identifier to the event and then forwards the event
 /// up to the server endpoint that owns the session.
 /// </summary>
 /// <param name="sender">
 /// The IPC module that is dispatching the event.
 /// </param>
 /// <param name="args">
 /// The details of the event being dispatched.
 /// </param>
 private void HandleDispatch(object sender, VfxIpcEventArgs args)
 {
     args.Token = _instanceGuid.ToString();
     EventHandler<VfxIpcEventArgs> tmp = EventDispatch;
     if (tmp != null)
     {
         tmp(this, args);
     }
 }
Пример #3
0
        /// <summary>
        /// The HandleIpcDispatch_EventClosed event handler is invoked
        /// when an IPC session disconnects from a peer system.
        /// </summary>
        /// <param name="sender">
        /// The IPC session that dispatched the event.
        /// </param>
        /// <param name="args">
        /// The details of the event being dispatched.
        /// </param>
        private void HandleIpcDispatch_EventClosed(object sender, VfxIpcEventArgs args)
        {
            // REC: Determine if there is currently an instance of
            // a FIX session associated with the IPC session:
            if (_mapIpcToFix.ContainsKey(args.Token))
            {
                // REC: Remove the binding between the FIX session
                // and the IPC session, since the IPC session has been
                // disconnected and can not be used by the FIX session
                // for any other operations:
                if (_mapFixToIpc.ContainsKey(_mapIpcToFix[args.Token]))
                {
                    _mapFixToIpc.Remove(_mapIpcToFix[args.Token]);
                }

                // REC: Notify the associated FIX session that the
                // connection has been broken:
                _mapFixSessions[_mapIpcToFix[args.Token]].HandleDisconnect();

            }
        }
Пример #4
0
 private void HandleIpcDispatch_EventMessage(object sender, VfxIpcEventArgs args)
 {
     if (_mapIpcToFix.ContainsKey(args.Token))
     {
         _mapFixSessions[_mapIpcToFix[args.Token]].HandleRxMessage(args.EventData);
     }
 }
Пример #5
0
 /// <summary>
 /// The HandleTcpConnector_Success event handler is invoked
 /// in response to the tcp connector establishing a connection
 /// to the peer system.
 /// </summary>
 /// <param name="sender">
 /// The connector that is dispatching the event.
 /// </param>
 /// <param name="args">
 /// The event details that are associated with the event.
 /// </param>
 private void HandleTcpConnector_Success(object sender, VfxTcpConnectorEventArgs args)
 {
     // REC: Translate the connector's success notification
     // into the corresponding IPC event and dispatch it:
     EventHandler<VfxIpcEventArgs> tmpDispatch = EventDispatch;
     if (tmpDispatch != null)
     {
         VfxIpcEventArgs tmpArgs = new VfxIpcEventArgs(VfxIpcEventTypes.Event_Connect_Success);
         tmpDispatch(this, tmpArgs);
     }
 }
Пример #6
0
 /// <summary>
 /// The HandleIpcDispatch event handler is invoked in response to
 /// an IPC session raising an event. The server service examines
 /// the token/sessionId that is contained in the event arguments
 /// and uses that information to demultiplex the details of the
 /// event to the corresponding FIX session.
 /// </summary>
 /// <param name="sender">
 /// The endpoint session that generated the event.
 /// </param>
 /// <param name="args">
 /// The details of the event that was generated.
 /// </param>
 private void HandleIpcDispatch(object sender, VfxIpcEventArgs args)
 {
     switch (args.EventType)
     {
         case VfxIpcEventTypes.Event_Session_Opened:
             HandleIpcDispatch_EventOpened(sender, args);
             break;
         case VfxIpcEventTypes.Event_Session_Closed:
             HandleIpcDispatch_EventClosed(sender, args);
             break;
         case VfxIpcEventTypes.Event_Session_Message:
             HandleIpcDispatch_EventMessage(sender, args);
             break;
         default:
             break;
     }
 }
Пример #7
0
 /// <summary>
 /// The HandleDispatch event handler is invoked in response to
 /// one of the IPC sessions dispatching an event to the endpoint.
 /// </summary>
 /// <param name="sender">
 /// The IPC session that is dispatching the event.
 /// </param>
 /// <param name="args">
 /// The details of the event being dispatched. The Token property
 /// of the event args instance will be set to the session id of the
 /// session that generated the event so that subscribers know which
 /// of the endpoint's sessions the event originated from.
 /// </param>
 private void HandleDispatch(object sender, VfxIpcEventArgs args)
 {
     EventHandler<VfxIpcEventArgs> tmp = EventDispatch;
     if (tmp != null)
     {
         tmp(this, args);
     }
 }
Пример #8
0
 /// <summary>
 /// The HandleIpc_Dispatch method is invoked in response
 /// to the IPC session handler dispatching an IPC event to
 /// the endpoint. The event is simply forwarded to the owner
 /// of the endpoint instance for processing.
 /// </summary>
 /// <param name="sender">
 /// The IPC session that is dispatching the event.
 /// </param>
 /// <param name="args">
 /// The details of the IPC event being dispatched.
 /// </param>
 private void HandleIpc_Dispatch(object sender, VfxIpcEventArgs args)
 {
     // REC: The incoming event from the underlying IPC session
     // is simply forwarded to the endpoint's owner:
     EventHandler<VfxIpcEventArgs> tmp = EventDispatch;
     if (tmp != null)
     {
         tmp(this, args);
     }
 }
Пример #9
0
        /// <summary>
        /// The CompleteRecv method is invoked in response to
        /// an asynchronous receive operation completing.
        /// </summary>
        /// <param name="ar"></param>
        private void CompleteRecv(IAsyncResult ar)
        {
            // REC: Retrieve the IO context that is associated with the
            // original asynchronous receive operation.
            IoContext rxContext = ar.AsyncState as IoContext;

            if (rxContext != null)
            {
                try
                {
                    // REC: Get the total number of bytes that were read
                    // from the peer system by this operation:
                    int rxBytes = rxContext._ipcSocket.EndReceive(ar);
                    if (rxBytes > 0)
                    {
                        // REC: Adjust the write index in the message block:
                        rxContext._ipcBuffer.WrIndex = rxContext._ipcBuffer.WrIndex + rxBytes;

                        // REC: Offload the received data onto a separate thread:
                        if (this._rxBuffering == true)
                        {
                            Socket rxSocket = rxContext._ipcSocket;
                            lock (this._synchRxPendingQueue)
                            {
                                // REC: Push the received data onto the queue so that
                                // it can be picked up by the secondary receive thread
                                // for further processing:
                                this._rxPendingQueue.Enqueue(rxContext);

                                // REC: If the queue was empty prior to this context
                                // being added to it, we need to signal the secondary
                                // receive thread so that it can start processing the
                                // data again:
                                if (this._rxPendingQueue.Count == 1)
                                {
                                    this._eventRxBuffer.Set();
                                }
                            }

                            // REC: Attempt to pull another context from the context
                            // queue so that we can receive more data:
                            IoContext rxNext;
                            if (this._rxContextQueue.Count > 0)
                            {
                                rxNext = this._rxContextQueue.Dequeue();
                            }
                            else
                            {
                                // REC: Note that this is BAD and will result in the
                                // exhaustion of all the system's memory if there is a
                                // continuous problem with the speed at which messages
                                // are being consumed on the receive thread...
                                rxNext = new IoContext(rxSocket, new VfxMsgBlock(8192));
                            }

                            // REC: Initiate a new receive operation, using the next
                            // available receive context:
                            InitiateRecv(rxNext);
                        }
                        else
                        {
                            // REC: If receive buffering has not been enabled then the
                            // data is dispatched directly to the module's owner:
                            EventHandler <VfxIpcEventArgs> tmp = EventDispatch;
                            if (tmp != null)
                            {
                                tmp(this, new VfxIpcEventArgs(rxContext._ipcBuffer));

                                // REC: Adjust the buffer to take into consideration
                                // any data that was read by the module's owner:
                                rxContext._ipcBuffer.Crunch();

                                // REC: Initiate another receive operation using the
                                // same receive buffer that was just processed:
                                InitiateRecv(rxContext);
                            }
                        }
                    }
                    else
                    {
                        _moduleState = ModuleStates.Module_State_Shutdown;

                        // REC: This might happen as the result of the
                        // user closing the session down.
                        EventHandler <VfxIpcEventArgs> tmp = EventDispatch;
                        if (tmp != null)
                        {
                            VfxIpcEventArgs dxArgs = new VfxIpcEventArgs(VfxIpcEventTypes.Event_Session_Closed);
                            tmp(this, dxArgs);
                        }
                    }
                }
                catch (SocketException)
                {
                    _moduleState = ModuleStates.Module_State_Shutdown;

                    // REC: This might happen as the result of the
                    // user closing the session down.
                    EventHandler <VfxIpcEventArgs> tmp = EventDispatch;
                    if (tmp != null)
                    {
                        VfxIpcEventArgs dxArgs = new VfxIpcEventArgs(VfxIpcEventTypes.Event_Session_Closed);
                        tmp(this, dxArgs);
                    }
                }
                catch (ObjectDisposedException)
                {
                    _moduleState = ModuleStates.Module_State_Shutdown;

                    // REC: This happens if the socket gets closed
                    // locally rather than being closed by the peer.
                    EventHandler <VfxIpcEventArgs> tmp = EventDispatch;
                    if (tmp != null)
                    {
                        VfxIpcEventArgs dxArgs = new VfxIpcEventArgs(VfxIpcEventTypes.Event_Session_Closed);
                        tmp(this, dxArgs);
                    }
                }
            }
        }
Пример #10
0
        /// <summary>
        /// The HandleIpc_EventOpened method is invoked in response
        /// to the IPC endpoint establishing a connection to the peer
        /// system that the service is interacting with.
        /// </summary>
        /// <param name="sender">
        /// The VfxIpcEndpoint that dispatched the event.
        /// </param>
        /// <param name="args">
        /// The details associated with the event.
        /// </param>
        private void HandleIpc_EventOpened(object sender, VfxIpcEventArgs args)
        {
            lock (_synch)
            {
                // REC: The IPC session is now established.
                _ipcEstablished = true;

                // REC: Adjust the service's current status:
                _serviceStatus = VfxFixServiceStatus.Service_Status_Opened;
                // REC: Dispatch the update to the service's subscribers:
                EventHandler<VfxFixServiceEventArgs> tmpDispatch_Update = EventDispatch;
                if (tmpDispatch_Update != null)
                {
                    VfxFixServiceEventArgs tmpArgs = new VfxFixServiceEventArgs(VfxFixServiceEventTypes.Event_Service_Updated, _serviceStatus);
                    tmpDispatch_Update(this, tmpArgs);
                }

                // REC: Retrieve the version definition from the version
                // definition registry and determine what kind of session
                // needs to be created in order to handle the connection:
                IVfxFixVxRegistry vxRegistry = this._localServices.GetService(typeof(IVfxFixVxRegistry)) as IVfxFixVxRegistry;

                // REC: Create a new instance of a FIX session to handle
                // the communication between the server and the peer:
                IVfxFixSession fixSession = null;

                // REC: Check the version definition in order to tell if
                // this is a FIX 4.x or FIX 5.x service:
                VfxFixVxRecord vxRecord = vxRegistry.Get(this._sxVersion);
                if (vxRecord.Layer.ToLower().CompareTo("combined") == 0)
                {
                    fixSession = new VfxFix4xClientSession();
                }
                else
                {
                    fixSession = new VfxFix5xClientSession();
                }

                _fixSession = fixSession;

                // REC: Initialize the session:
                _fixSession.Init(this._localServices, this);

                // REC: Construct an instance of the session wrapper
                // for the FIX application and bind it to the session
                // implementation that has been created:
                _appSession = new VfxFixClientSession(_fixSession);

                // REC: Notify the FIX session implementation that it
                // has been connected to a peer system:
                _fixSession.HandleConnect();
            }
        }
Пример #11
0
 /// <summary>
 /// The HandleIpc_EventMessage event handler is invoked in
 /// response to the service being notified that the IPC session
 /// has received some data from the peer system.
 /// </summary>
 /// <param name="sender">
 /// The IPC session that is dispatching the event.
 /// </param>
 /// <param name="args">
 /// The details of the IPC event being dispatched.
 /// </param>
 private void HandleIpc_EventMessage(object sender, VfxIpcEventArgs args)
 {
     lock (_synch)
     {
         _fixSession.HandleRxMessage(args.EventData);
     }
 }
Пример #12
0
        /// <summary>
        /// The HandleIpc_EventClosed event handler is invoked in
        /// response to the service being notified that the session
        /// has been disconnected from the peer system.
        /// </summary>
        /// <param name="sender">
        /// The IPC session that is dispatching the event.
        /// </param>
        /// <param name="args">
        /// The details of the IPC event being dispatched.
        /// </param>
        private void HandleIpc_EventClosed(object sender, VfxIpcEventArgs args)
        {
            lock (_synch)
            {
                // REC: The IPC session is no longer established:
                _ipcEstablished = false;

                // REC: Notify the FIX session that the peer system
                // is no longer connected:
                _fixSession.HandleDisconnect();

                // REC: Adjust the service's current status:
                _serviceStatus = VfxFixServiceStatus.Service_Status_Disconnected;
                EventHandler<VfxFixServiceEventArgs> tmpDispatch_Update = EventDispatch;
                if (tmpDispatch_Update != null)
                {
                    VfxFixServiceEventArgs tmpArgs = new VfxFixServiceEventArgs(VfxFixServiceEventTypes.Event_Service_Updated, _serviceStatus);
                    tmpDispatch_Update(this, tmpArgs);
                }

                // REC: If the service is closing, then the disconnection
                // of the IPC endpoint is the last thing that needs to be
                // completed before dispatching the stopped event back up
                // to the service's owner/subscribers:
                if (_serviceState == VfxFixServiceStates.Service_State_Closing)
                {
                    // REC: Adjust the service's current state:
                    _serviceState = VfxFixServiceStates.Service_State_Closed;
                    // REC: Adjust the service's current status:
                    _serviceStatus = VfxFixServiceStatus.Service_Status_Closed;

                    EventHandler<VfxFixServiceEventArgs> tmpDispatch_Stopped = EventDispatch;
                    if (tmpDispatch_Stopped != null)
                    {
                        VfxFixServiceEventArgs tmpArgs = new VfxFixServiceEventArgs(VfxFixServiceEventTypes.Event_Service_Stopped, _serviceStatus);
                        tmpDispatch_Stopped(this, tmpArgs);
                    }
                }
                else
                {
                    // REC: If the service is not configured to reconnect
                    // to the peer system, then it is now stopped:

                    // NOTE: Add reconnect logic here!

                    // REC: Adjust the service's current state:
                    _serviceState = VfxFixServiceStates.Service_State_Closed;
                    // REC: Adjust the service's current status:
                    _serviceStatus = VfxFixServiceStatus.Service_Status_Closed;

                    EventHandler<VfxFixServiceEventArgs> tmpDispatch_Stopped = EventDispatch;
                    if (tmpDispatch_Stopped != null)
                    {
                        VfxFixServiceEventArgs tmpArgs = new VfxFixServiceEventArgs(VfxFixServiceEventTypes.Event_Service_Stopped, _serviceStatus);
                        tmpDispatch_Stopped(this, tmpArgs);
                    }
                }
            }
        }
Пример #13
0
        /// <summary>
        /// The CompleteRecv method is invoked in response to
        /// an asynchronous receive operation completing.
        /// </summary>
        /// <param name="ar"></param>
        private void CompleteRecv(IAsyncResult ar)
        {
            // REC: Retrieve the IO context that is associated with the
            // original asynchronous receive operation.
            IoContext rxContext = ar.AsyncState as IoContext;
            if (rxContext != null)
            {
                try
                {
                    // REC: Get the total number of bytes that were read
                    // from the peer system by this operation:
                    int rxBytes = rxContext._ipcSocket.EndReceive(ar);
                    if (rxBytes > 0)
                    {
                        // REC: Adjust the write index in the message block:
                        rxContext._ipcBuffer.WrIndex = rxContext._ipcBuffer.WrIndex + rxBytes;

                        // REC: Offload the received data onto a separate thread:
                        if (this._rxBuffering == true)
                        {
                            Socket rxSocket = rxContext._ipcSocket;
                            lock (this._synchRxPendingQueue)
                            {
                                // REC: Push the received data onto the queue so that
                                // it can be picked up by the secondary receive thread
                                // for further processing:
                                this._rxPendingQueue.Enqueue(rxContext);

                                // REC: If the queue was empty prior to this context
                                // being added to it, we need to signal the secondary
                                // receive thread so that it can start processing the
                                // data again:
                                if (this._rxPendingQueue.Count == 1)
                                {
                                    this._eventRxBuffer.Set();
                                }
                            }

                            // REC: Attempt to pull another context from the context
                            // queue so that we can receive more data:
                            IoContext rxNext;
                            if (this._rxContextQueue.Count > 0)
                            {
                                rxNext = this._rxContextQueue.Dequeue();
                            }
                            else
                            {
                                // REC: Note that this is BAD and will result in the
                                // exhaustion of all the system's memory if there is a
                                // continuous problem with the speed at which messages
                                // are being consumed on the receive thread...
                                rxNext = new IoContext(rxSocket, new VfxMsgBlock(8192));
                            }

                            // REC: Initiate a new receive operation, using the next
                            // available receive context:
                            InitiateRecv(rxNext);
                        }
                        else
                        {
                            // REC: If receive buffering has not been enabled then the
                            // data is dispatched directly to the module's owner:
                            EventHandler<VfxIpcEventArgs> tmp = EventDispatch;
                            if (tmp != null)
                            {
                                tmp(this, new VfxIpcEventArgs(rxContext._ipcBuffer));

                                // REC: Adjust the buffer to take into consideration
                                // any data that was read by the module's owner:
                                rxContext._ipcBuffer.Crunch();

                                // REC: Initiate another receive operation using the
                                // same receive buffer that was just processed:
                                InitiateRecv(rxContext);
                            }
                        }
                    }
                    else
                    {
                        _moduleState = ModuleStates.Module_State_Shutdown;

                        // REC: This might happen as the result of the
                        // user closing the session down.
                        EventHandler<VfxIpcEventArgs> tmp = EventDispatch;
                        if (tmp != null)
                        {
                            VfxIpcEventArgs dxArgs = new VfxIpcEventArgs(VfxIpcEventTypes.Event_Session_Closed);
                            tmp(this, dxArgs);
                        }
                    }
                }
                catch (SocketException)
                {
                    _moduleState = ModuleStates.Module_State_Shutdown;

                    // REC: This might happen as the result of the
                    // user closing the session down.
                    EventHandler<VfxIpcEventArgs> tmp = EventDispatch;
                    if (tmp != null)
                    {
                        VfxIpcEventArgs dxArgs = new VfxIpcEventArgs(VfxIpcEventTypes.Event_Session_Closed);
                        tmp(this, dxArgs);
                    }
                }
                catch (ObjectDisposedException)
                {
                    _moduleState = ModuleStates.Module_State_Shutdown;

                    // REC: This happens if the socket gets closed
                    // locally rather than being closed by the peer.
                    EventHandler<VfxIpcEventArgs> tmp = EventDispatch;
                    if (tmp != null)
                    {
                        VfxIpcEventArgs dxArgs = new VfxIpcEventArgs(VfxIpcEventTypes.Event_Session_Closed);
                        tmp(this, dxArgs);
                    }
                }
            }
        }