/// <include file='InterfaceDocumentationComments.xml' path='doc/members/member[@name="M:MethodInvocationRemoting.IRemoteSender.Send(System.String)"]/*'/>
        public void Send(string message)
        {
            metricsUtilities.Begin(new MessageSendTime());

            try
            {
                CheckNotDisposed();
                CheckConnectionOpen();

                // Send a message
                ITextMessage textMessage = session.CreateTextMessage(message);
                textMessage.Properties.SetString(filterIdentifier, messageFilter);
                try
                {
                    producer.Send(textMessage);
                }
                catch (Exception e)
                {
                    throw new Exception("Error sending message.", e);
                }
            }
            catch (Exception e)
            {
                metricsUtilities.CancelBegin(new MessageSendTime());
                throw;
            }

            metricsUtilities.End(new MessageSendTime());
            metricsUtilities.Increment(new MessageSent());
            loggingUtilities.Log(this, LogLevel.Information, "Message sent.");
        }
        //------------------------------------------------------------------------------
        //
        // Method: CompressString
        //
        //------------------------------------------------------------------------------
        /// <summary>
        /// Compresses a string.
        /// </summary>
        /// <param name="inputString">The string to compress.</param>
        /// <returns>The compressed string.</returns>
        private string CompressString(string inputString)
        {
            metricsUtilities.Begin(new StringCompressTime());

            // Note that no try/catch block is included in this method.  According to the .NET documentation, most methods here will only cause exceptions in cases like null parameters being passed (e.g. in the case if UTF8Encoding.GetBytes() and Convert.ToBase64String()), which would be very unlikely to occur if these classes are used in the intended context.

            byte[] inputStringBytes = stringEncoding.GetBytes(inputString);
            byte[] compressedByteArray;

            // Use the GZipStream class to compress the bytes of the string
            using (MemoryStream compressedStringStream = new MemoryStream())
                using (GZipStream compressor = new GZipStream(compressedStringStream, CompressionMode.Compress))
                {
                    compressor.Write(inputStringBytes, 0, inputStringBytes.Length);
                    compressor.Close();
                    compressedByteArray = compressedStringStream.ToArray();
                    compressedStringStream.Close();
                }

            // Convert the compressed bytes to a base 64 string
            string returnString = Convert.ToBase64String(compressedByteArray);

            metricsUtilities.End(new StringCompressTime());
            metricsUtilities.Increment(new StringCompressed());
            metricsUtilities.Add(new CompressedStringSize(returnString.Length));
            loggingUtilities.LogCompressedString(this, returnString);

            return(returnString);
        }
Пример #3
0
        /// <include file='InterfaceDocumentationComments.xml' path='doc/members/member[@name="M:MethodInvocationRemoting.IRemoteReceiver.Receive"]/*'/>
        public string Receive()
        {
            CheckNotDisposed();
            string returnMessage = "";

            cancelRequest = false;

            try
            {
                while (cancelRequest == false)
                {
                    if (fileSystem.CheckFileExists(messageFilePath) == true)
                    {
                        if (fileSystem.CheckFileExists(lockFilePath) == false)
                        {
                            metricsUtilities.Begin(new MessageReceiveTime());

                            try
                            {
                                returnMessage = messageFile.ReadAll();
                                fileSystem.DeleteFile(messageFilePath);
                            }
                            catch (Exception e)
                            {
                                metricsUtilities.CancelBegin(new MessageReceiveTime());
                                throw;
                            }

                            metricsUtilities.End(new MessageReceiveTime());
                            metricsUtilities.Increment(new MessageReceived());
                            metricsUtilities.Add(new ReceivedMessageSize(returnMessage.Length));
                            loggingUtilities.LogMessageReceived(this, returnMessage);
                            break;
                        }
                    }
                    else
                    {
                        waitingForTimeout = true;
                        if (readLoopTimeout > 0)
                        {
                            System.Threading.Thread.Sleep(readLoopTimeout);
                        }
                        waitingForTimeout = false;
                    }
                }
            }
            catch (Exception e)
            {
                throw new Exception("Error receiving message.", e);
            }

            return(returnMessage);
        }
Пример #4
0
        /// <include file='InterfaceDocumentationComments.xml' path='doc/members/member[@name="M:MethodInvocationRemoting.IMethodInvocationSerializer.Serialize(MethodInvocationRemoting.IMethodInvocation)"]/*'/>
        public string Serialize(IMethodInvocation inputMethodInvocation)
        {
            metricsUtilities.Begin(new MethodInvocationSerializeTime());

            string returnString = "";

            try
            {
                returnString = SerializeObject(inputMethodInvocation);
            }
            catch (Exception e)
            {
                metricsUtilities.CancelBegin(new MethodInvocationSerializeTime());
                throw new SerializationException("Failed to serialize method invocation '" + inputMethodInvocation.Name + "'.", inputMethodInvocation, e);
            }

            metricsUtilities.End(new MethodInvocationSerializeTime());
            metricsUtilities.Increment(new MethodInvocationSerialized());
            metricsUtilities.Add(new SerializedMethodInvocationSize(returnString.Length));
            loggingUtilities.LogSerializedItem(this, returnString, "method invocation");

            return(returnString);
        }
        /// <include file='InterfaceDocumentationComments.xml' path='doc/members/member[@name="M:MethodInvocationRemoting.IMethodInvocationRemoteSender.InvokeMethod(MethodInvocationRemoting.IMethodInvocation)"]/*'/>
        public object InvokeMethod(IMethodInvocation inputMethodInvocation)
        {
            metricsUtilities.Begin(new RemoteMethodSendTime());

            object returnValue;

            try
            {
                // Check that inputted method invocation does not have a void return type.
                if (inputMethodInvocation.ReturnType == null)
                {
                    throw new ArgumentException("Method invocation cannot have a void return type.", "inputMethodInvocation");
                }

                string serializedReturnValue = SerializeAndSend(inputMethodInvocation);
                try
                {
                    returnValue = serializer.DeserializeReturnValue(serializedReturnValue);
                }
                catch (Exception e)
                {
                    throw new Exception("Failed to deserialize return value.", e);
                }
            }
            catch (Exception e)
            {
                metricsUtilities.CancelBegin(new RemoteMethodSendTime());
                throw;
            }

            metricsUtilities.End(new RemoteMethodSendTime());
            metricsUtilities.Increment(new RemoteMethodSent());
            loggingUtilities.Log(this, LogLevel.Information, "Invoked method '" + inputMethodInvocation.Name + "'.");

            return(returnValue);
        }
        /// <include file='InterfaceDocumentationComments.xml' path='doc/members/member[@name="M:MethodInvocationRemoting.IMethodInvocationRemoteReceiver.Receive"]/*'/>
        public void Receive()
        {
            cancelRequest = false;

            receiveLoopThread = new Thread(delegate()
            {
                while (cancelRequest == false)
                {
                    try
                    {
                        string serializedMethodInvocation = receiver.Receive();
                        if (serializedMethodInvocation != "")
                        {
                            metricsUtilities.Begin(new RemoteMethodReceiveTime());

                            IMethodInvocation receivedMethodInvocation;

                            try
                            {
                                receivedMethodInvocation = serializer.Deserialize(serializedMethodInvocation);
                                OnMethodInvocationReceived(new MethodInvocationReceivedEventArgs(receivedMethodInvocation));
                            }
                            catch (Exception e)
                            {
                                metricsUtilities.CancelBegin(new RemoteMethodReceiveTime());
                                throw;
                            }

                            loggingUtilities.Log(this, LogLevel.Information, "Received method invocation '" + receivedMethodInvocation.Name + "'.");
                        }
                    }
                    catch (Exception e)
                    {
                        throw new Exception("Failed to invoke method.", e);
                    }
                }
            });
            receiveLoopThread.Name = "MethodInvocationRemoting.MethodInvocationRemoteReceiver message receive worker thread.";
            receiveLoopThread.Start();
        }
        /// <include file='InterfaceDocumentationComments.xml' path='doc/members/member[@name="M:MethodInvocationRemoting.IRemoteSender.Send(System.String)"]/*'/>
        public void Send(string message)
        {
            metricsUtilities.Begin(new MessageSendTime());

            CheckNotDisposed();
            CheckConnected();

            try
            {
                EncodeAndSend(message);
            }
            catch (Exception e)
            {
                HandleExceptionAndResend(e, message);
            }

            IncrementMessageSequenceNumber();

            metricsUtilities.End(new MessageSendTime());
            metricsUtilities.Increment(new MessageSent());
            loggingUtilities.Log(this, LogLevel.Information, "Message sent and acknowledged.");
        }
        /// <include file='InterfaceDocumentationComments.xml' path='doc/members/member[@name="M:MethodInvocationRemoting.IRemoteSender.Send(System.String)"]/*'/>
        public void Send(string message)
        {
            metricsUtilities.Begin(new MessageSendTime());

            CheckNotDisposed();

            try
            {
                // Lock file is created before data is written to the message file
                //   The FileRemoteReceiver class checks for the absence of the lock file to prevent attempting to open the message file when it is partially written and causing an exception
                lockFile.WriteAll("");
                messageFile.WriteAll(message);
                fileSystem.DeleteFile(lockFilePath);
            }
            catch (Exception e)
            {
                metricsUtilities.CancelBegin(new MessageSendTime());
                throw new Exception("Error sending message.", e);
            }

            metricsUtilities.End(new MessageSendTime());
            metricsUtilities.Increment(new MessageSent());
            loggingUtilities.Log(this, LogLevel.Information, "Message sent.");
        }
        /// <include file='InterfaceDocumentationComments.xml' path='doc/members/member[@name="M:MethodInvocationRemoting.IRemoteReceiver.Receive"]/*'/>
        public string Receive()
        {
            cancelRequest = false;
            CheckNotDisposed();
            CheckConnected();
            int    messageSequenceNumber = -1;
            string returnMessage         = "";

            while (cancelRequest == false)
            {
                // Check if there are any pending connections which would indicate the TcpRemoteSender has encountered an error and reconnected
                if (listener.Pending() == true)
                {
                    logger.Log(this, LogLevel.Warning, "New connection detected.  Attempting reconnect.");
                    AttemptConnect();
                    metricsUtilities.Increment(new TcpRemoteReceiverReconnected());
                }

                // Check if any data has been received from the TcpRemoteSender, and handle and retry if an exception occurs
                int availableData = 0;
                try
                {
                    availableData = client.Available;
                }
                catch (Exception e)
                {
                    availableData = HandleExceptionAndCheckAvailableData(e);
                }

                // If data has been received, attempt to read and parse it, and handle and retry if an exception occurs
                if (availableData != 0)
                {
                    metricsUtilities.Begin(new MessageReceiveTime());

                    MessageParseState parseState   = MessageParseState.StartOfMessage;
                    Queue <byte>      messageBytes = null; // Holds the bytes which form the body of the message received

                    try
                    {
                        messageBytes = SetupAndReadMessage(ref parseState, ref messageSequenceNumber);
                    }
                    catch (Exception e)
                    {
                        messageBytes = HandleExceptionAndRereadMessage(e, ref parseState, ref messageSequenceNumber);
                    }

                    // If the complete message has been read, break out of the current while loop
                    //   If the complete message was not read it would have been caused by a cancel request, or by a pending connection which is handled outside this block
                    if ((cancelRequest == false) && (parseState == MessageParseState.ReadCompleteMessage))
                    {
                        // If the sequence number of the message is the same as the last received message, then discard the message
                        //   This situation can be caused by the connection breaking before the sender received the last acknowledgment
                        if (messageSequenceNumber != lastMessageSequenceNumber)
                        {
                            lastMessageSequenceNumber = messageSequenceNumber;
                            returnMessage             = stringEncoding.GetString(messageBytes.ToArray());

                            metricsUtilities.End(new MessageReceiveTime());
                            metricsUtilities.Increment(new MessageReceived());
                            metricsUtilities.Add(new ReceivedMessageSize(returnMessage.Length));
                            loggingUtilities.LogMessageReceived(this, returnMessage);
                            break;
                        }
                        else
                        {
                            metricsUtilities.Increment(new TcpRemoteReceiverDuplicateSequenceNumber());
                            logger.Log(this, LogLevel.Warning, "Duplicate message with sequence number " + messageSequenceNumber + " received.  Message discarded.");
                            // Reset variables
                            messageSequenceNumber = -1;
                            returnMessage         = "";
                        }
                    }

                    metricsUtilities.End(new MessageReceiveTime());
                }

                waitingForRetry = true;
                if (receiveRetryInterval > 0)
                {
                    Thread.Sleep(receiveRetryInterval);
                }
                waitingForRetry = false;
            }

            return(returnMessage);
        }
Пример #10
0
        //------------------------------------------------------------------------------
        //
        // Method: DecompressString
        //
        //------------------------------------------------------------------------------
        /// <summary>
        /// Decompresses a string.
        /// </summary>
        /// <param name="inputString">The string to decompress.</param>
        /// <returns>The decompressed string.</returns>
        private string DecompressString(string inputString)
        {
            metricsUtilities.Begin(new StringDecompressTime());

            decompressing = true;

            List <byte[]> readBuffers = new List <byte[]>();
            int           currentReadBufferPosition = 0;
            string        returnString = "";

            try
            {
                // Decode from base 64
                byte[] encodedBytes = Convert.FromBase64String(inputString);
                using (MemoryStream decompressedStringStream = new MemoryStream(encodedBytes))
                    using (GZipStream decompressor = new GZipStream(decompressedStringStream, CompressionMode.Decompress))
                    {
                        int bytesRead = -1;
                        while (bytesRead != 0)
                        {
                            // If the list of buffers is empty, or the read position in the current (last) buffer is at the end of the buffer, then create a new read buffer
                            if ((readBuffers.Count == 0) || (currentReadBufferPosition == decompressionBufferSize))
                            {
                                readBuffers.Add(new byte[decompressionBufferSize]);
                                currentReadBufferPosition = 0;

                                metricsUtilities.Increment(new RemoteReceiverDecompressorReadBufferCreated());
                            }
                            bytesRead = decompressor.Read(readBuffers[readBuffers.Count - 1], currentReadBufferPosition, decompressionBufferSize - currentReadBufferPosition);
                            currentReadBufferPosition = currentReadBufferPosition + bytesRead;
                        }
                        decompressor.Close();
                        decompressedStringStream.Close();
                    }

                // Create decompressed byte array with size as buffer size times the number of buffers (except the last buffer), plus the position within the last buffer
                byte[] decompressedBytes = new byte[((readBuffers.Count - 1) * decompressionBufferSize) + currentReadBufferPosition];
                // Copy the contents of the read buffers into the decompressed byte array
                int decompressedBytesPosition = 0;
                foreach (byte[] currentReadBuffer in readBuffers)
                {
                    if (currentReadBuffer != readBuffers[readBuffers.Count - 1])
                    {
                        Array.Copy(currentReadBuffer, 0, decompressedBytes, decompressedBytesPosition, decompressionBufferSize);
                        decompressedBytesPosition = decompressedBytesPosition + decompressionBufferSize;
                    }
                    else
                    {
                        Array.Copy(currentReadBuffer, 0, decompressedBytes, decompressedBytesPosition, currentReadBufferPosition);
                    }
                }

                returnString = stringEncoding.GetString(decompressedBytes);
            }
            catch (Exception e)
            {
                metricsUtilities.CancelBegin(new StringDecompressTime());
                throw new Exception("Error decompressing message.", e);
            }

            metricsUtilities.End(new StringDecompressTime());
            metricsUtilities.Increment(new StringDecompressed());
            loggingUtilities.LogDecompressedString(this, returnString);

            decompressing = false;
            return(returnString);
        }