Beispiel #1
0
        /// <summary>
        /// Monitors the queue of pending commands and causes the next pending request
        /// to be sent to Cornerstone.
        /// </summary>
        private void MonitorQueue()
        {
            while (true)
            {
                //Wait until we have a request in the queue
                _requestEnqueued.WaitOne();

                //Check to see if we are already processing another command. We do not
                //want to process the next command until a response has been returned for
                //command currently being processed.
                if (_pendingCommand == null)
                {
                    //Prepare to send this command. Grab it off of the queue.
                    SendDataEventArgs eventArgs;
                    if (_pendingCommands.TryDequeue(out eventArgs))
                    {
                        //Make sure the command has data to be sent.
                        var data = eventArgs.Data;
                        if (data != null)
                        {
                            //If the command does not already have an cookie, we will give
                            //it a GUID as its cookie.
                            if (String.IsNullOrEmpty(eventArgs.Cookie))
                            {
                                eventArgs.Cookie = Guid.NewGuid().ToString();
                            }

                            if (data.StartsWith("<"))
                            {
                                var document = XDocument.Parse(data);
                                //Add on the cookie ID and the current request culture to the data XML.
                                document.Root.SetAttributeValue("Cookie", eventArgs.Cookie);
                                document.Root.SetAttributeValue("Culture", RequestCulture);
                                data = document.ToString();
                            }

                            //Keep track of this command.
                            _pendingCommand = eventArgs;

                            //Fire the command off to Cornerstone.
                            SendData(EncodingToUse.GetBytes(data));

                            //Let the sender know that the data went out.
                            if (eventArgs.Sender != null)
                            {
                                eventArgs.Sender.TrafficOut(data);
                            }
                        }
                    }
                }

                if (_pendingCommands.Count > 0)
                {
                    _requestEnqueued.Set();
                }
            }
        }
Beispiel #2
0
        /// <summary>
        /// Called when data is received from Cornerstone. This method will be called multiple
        /// times until all of the data in response to a command is received. When Cornerstone
        /// responds to a command, it will first send the number of bytes contained in the command
        /// response, followed by the command response itself. This method uses the ReceivedDataStateObject
        /// to keep a running compilation of the data received in the case where Cornerstone's response
        /// does not arrive all at once.
        /// </summary>
        /// <param name="ar">Received data.</param>
        private void DataReceived(IAsyncResult ar)
        {
            try
            {
                var stateObject = ar.AsyncState as ReceivedDataStateObject;
                if (stateObject == null)
                {
                    //The state object is null which indicates that this is a new response and not a continuation
                    //of a previous response.
                    var bytes = _tcpClient.GetStream().EndRead(ar);

                    // Detect the stream ended.
                    if (bytes == 0)
                    {
                        return;
                    }

                    //Get the number of bytes contained in the command response.
                    int length = BitConverter.ToInt32(_receiveBuffer, 0);
                    //Create a state object to hold onto the response.
                    stateObject = new ReceivedDataStateObject {
                        Length = length
                    };

                    EventAggregatorContext.Current.GetEvent <RecordDataTrafficEvent>().Publish(new DataTrafficSentReceivedViewModel(_receiveBuffer, false, bytes));

                    //check if we have received more than 4 bytes. The 4 bytes contains the length of the following
                    //data. If we have received more than the 4 bytes, we need to add that to our buffer.
                    if (bytes > 4)
                    {
                        stateObject.Length -= (bytes - 4);
                        stateObject.Data   += EncodingToUse.GetString(_receiveBuffer, 4, bytes - 4);

                        //check if we have received it all.
                        if (stateObject.Length <= 0)
                        {
                            //process the data we have received.
                            ProcessReceivedData(stateObject);
                        }
                    }
                    //Set ourselves up to be notified when more data arrives.
                    _tcpClient.GetStream().BeginRead(_receiveBuffer, 0, _receiveBuffer.Length, DataReceived, stateObject);
                }
                else
                {
                    //Find out how many bytes are in the response.
                    var bytes = _tcpClient.GetStream().EndRead(ar);
                    //Subtract them from the total that we are expecting.
                    stateObject.Length -= bytes;
                    //Append the data to our running compilation.
                    stateObject.Data += EncodingToUse.GetString(_receiveBuffer, 0, bytes);

                    EventAggregatorContext.Current.GetEvent <RecordDataTrafficEvent>().Publish(new DataTrafficSentReceivedViewModel(_receiveBuffer, false, bytes));

                    if (stateObject.Length > 0)
                    {
                        //We are still waiting for more of the response, so starting waiting....
                        _tcpClient.GetStream().BeginRead(_receiveBuffer, 0, _receiveBuffer.Length, DataReceived, stateObject);
                    }
                    else
                    {
                        //process the data we have received.
                        ProcessReceivedData(stateObject);

                        //Start waiting for the next response.
                        _tcpClient.GetStream().BeginRead(_receiveBuffer, 0, _receiveBuffer.Length, DataReceived, null);
                    }
                }
            }
            catch
            {
                Disconnect();
            }
        }