Example #1
0
        private void MessageDispatcher_NOTIFY(MsgSourceInfo src, IMessage imsg)
        {
            try
            {
                // convert remoting message to the array
                byte[] buffer = RemotingConvert.ToArray(imsg);

                // notify
                IRemotingResponse ro = (IRemotingResponse)Activator.GetObject(typeof(IRemotingResponse), NotifyUrl);
                ro.ResponseNotify(src, buffer);

                // echo
                Trace.WriteLine(string.Format("[{0}]MSMQChannel.Receiver.MessageDispatcher_NOTIFY done, url={1}",
                                              ChannelName, NotifyUrl));
            }
            catch (Exception ex)
            {
                string strErr = string.Format("[{0}]MSMQChannel.Receiver.MessageDispatcher_NOTIFY failed at url={1}, error={2};",
                                              ChannelName, NotifyUrl, ex.Message);
                WriteLogMsg(strErr, EventLogEntryType.Error);
            }
        }
Example #2
0
        public void MessageWorker(object source)
        {
            // scope state
            int                     intNumberOfWorkers = 0;
            bool                    bTransactional     = true;
            Exception               exception          = null;
            IMessage                msgReq             = null;
            IMessage                msgRsp             = null;
            Message                 msg  = null;
            MessageQueue            mq   = source as MessageQueue;
            MessageQueueTransaction mqtx = new MessageQueueTransaction();

            try
            {
                // check-in
                intNumberOfWorkers = Interlocked.Increment(ref m_NumberOfWorkers);

                // transactional flag
                bTransactional = mq.Transactional;

                // echo
                Trace.WriteLine(string.Format("[{0}]MSMQChannel.Receiver:MessageWorker check-in #{1}, isTxQueue={2}",
                                              ChannelName, intNumberOfWorkers, bTransactional));

                // begin single transaction
                if (bTransactional)
                {
                    mqtx.Begin();
                }

                // retrieve transactional message (message has been retrieved from the queue)
                msg = mq.Receive(TimeSpan.FromSeconds(1), mqtx);

                // signal to manager
                if (intNumberOfWorkers < MaxNumberOfWorkers)
                {
                    m_EventMgr.Set();
                }
                else
                {
                    m_EventMgr.Reset();
                }

                // remoting message from the client
                msgReq = msg.Body as IMessage;

                // work around!!!
                msgReq.Properties[MSMQChannelProperties.Uri] = msgReq.Properties[MSMQChannelProperties.ObjectUri];

                // option: target object
                if (NotifyUrl == MSMQChannelDefaults.EmptyStr)
                {
                    // Dispatch message to the remoting object
                    msgRsp = MessageDispatcher(msgReq, msg.BodyStream);
                }
                else
                {
                    // pack the source info
                    MsgSourceInfo src = new MsgSourceInfo();
                    src.Acknowledgment    = msg.Acknowledgment;
                    src.MessageSentTime   = msg.SentTime;
                    src.ResponseQueuePath = msg.ResponseQueue == null ? "null" : msg.ResponseQueue.Path;
                    src.ReportQueuePath   = mq.Path;

                    // Call Notification Object
                    MessageDispatcher_NOTIFY(src, msgReq);
                }

                // commit transaction (message is going to be removed from the queue)
                if (bTransactional)
                {
                    mqtx.Commit();
                }

                // echo
                Trace.WriteLine(string.Format("[{0}]MSMQChannel.Receiver.MessageWorker The call has been invoked on {1}",
                                              ChannelName, msg.Label));

                // response
                if (AcknowledgeUrl != MSMQChannelDefaults.EmptyStr)
                {
                    // workaround
                    if (msgRsp != null)
                    {
                        msgRsp.Properties[MSMQChannelProperties.Uri]        = msgReq.Properties[MSMQChannelProperties.Uri];
                        msgRsp.Properties[MSMQChannelProperties.MethodName] = msgReq.Properties["__MethodName"];
                        msgRsp.Properties[MSMQChannelProperties.TypeName]   = msgReq.Properties["__TypeName"];
                    }

                    // remoting notification
                    MessageDispatcher_ACK(msgRsp == null ? msgReq : msgRsp);
                }
            }
            catch (MessageQueueException ex)
            {
                // save for a notification issue
                exception = ex;

                // echo
                Trace.WriteLine(string.Format("[{0}]MSMQChannel.Receiver:MessageWorker error/warning = {1}", ChannelName, ex.Message));
            }
            catch (Exception ex)
            {
                // save for a notification issue
                exception = ex;

                // echo
                Trace.WriteLine(string.Format("[{0}]MSMQChannel.Receiver:MessageWorker error/warning = {1}", ChannelName, ex.Message));
            }
            finally
            {
                bool bRetryDone = false;

                if (bTransactional && mqtx.Status == MessageQueueTransactionStatus.Pending)
                {
                    // check the retry filter
                    int posRules = (RetryFilter == MSMQChannelDefaults.EmptyStr) ? 0 : RetryFilter.IndexOf(exception.Message);
                    if (posRules < 0 && exception.InnerException != null)
                    {
                        posRules = RetryFilter.IndexOf(exception.InnerException.Message);
                    }

                    // send message to the retry queue
                    if (msg != null && msgReq != null && RetryCounter > 0 && posRules < 0)
                    {
                        // remoting notification
                        bRetryDone = MessageDispatcher_RETRY(mqtx, msg, msgReq);
                    }

                    // commit transaction (message is going to be removed from the queue)
                    mqtx.Commit();
                }

                // exception notification
                if (exception != null && msg != null && msgReq != null && bRetryDone == false && ExceptionUrl != MSMQChannelDefaults.EmptyStr)
                {
                    // remoting notification
                    MessageDispatcher_ERROR(msgReq, exception);
                }

                // clean-up
                if (msg != null)
                {
                    msg.Dispose();
                }

                // check-out
                intNumberOfWorkers = Interlocked.Decrement(ref m_NumberOfWorkers);
                if (intNumberOfWorkers < MaxNumberOfWorkers)
                {
                    m_EventMgr.Set();
                }
                else
                {
                    m_EventMgr.Reset();
                }

                // echo
                Trace.WriteLine(string.Format("[{0}]MSMQChannel.Receiver:MessageWorker check-out #{1}, isTxQueue={2}",
                                              ChannelName, intNumberOfWorkers, bTransactional));
            }
        }