示例#1
0
文件: Listener.cs 项目: yallie/zyan
        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);
            }
        }
示例#2
0
文件: Listener.cs 项目: yallie/zyan
        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));
            }
        }