使用MSMQ的格式化程序出现问题 [英] Problem with formatters using MSMQ

查看:101
本文介绍了使用MSMQ的格式化程序出现问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我正在构建一个MSMQ应用程序.我正在以文本格式从应用程序写入队列.我的Windows服务从MSMQ提取它,并将其放入数据库中.

但是我在这里面临的问题是消息中包含了MSMQ中的完整字符串.我想知道我在做什么错.

请帮忙.
请找到以下附件文件以供参考.

谢谢

Hi,

I am building a MSMQ application. I am writing from an application to a queue in Text Format . And my windows service picks it up from the MSMQ and puts it in the database.

But the problem I am facing here is that the complete string in the MSMQ is going into the message.. ITs not getting splitted up into the text fomatter pattern. I would like to know what I am doing wrong.

Please help.
Please find the below attached files for reference.

Thanks

MSMQLogDistributor.cs - MSMQ to Database 
using System;
using System.Diagnostics;
using System.IO;
using System.Messaging;
using System.Runtime.Serialization;
using System.Security.Principal;
using System.Text;
using Microsoft.Practices.EnterpriseLibrary.Logging.Formatters;
using Microsoft.Practices.EnterpriseLibrary.Logging;
using DTG.Global.Utility.Logging.LogService.Instrumentation;
using DTG.Global.Utility.Logging.LogService.Properties;
using DTG.Global.Object;
using DTG.Global.Utility.Logging;

namespace DTG.Global.Utility.Logging.LogService
{
    /// <summary>
    /// Receive new log messages from MSMQ and distribute each log entry.
    /// </summary>
    public class MsmqLogDistributor
    {
        private bool isCompleted = true;
        private bool stopReceiving = false;

        private LogWriter logWriter;
        private string msmqPath;

        private DistributorEventLogger eventLogger;

        /// <summary>
        /// Setup the queue and the formatter of the messages.
        /// </summary>
        public MsmqLogDistributor(LogWriter logWriter, string msmqPath, 

DistributorEventLogger eventLogger)
        {
            this.logWriter = logWriter;
            this.msmqPath = msmqPath;
            this.eventLogger = eventLogger;
        }

        /// <summary>
        /// Read-only property to check if the synchronous receive is completed.
        /// </summary>
        public virtual bool IsCompleted
        {
            get { return this.isCompleted; }
        }

        /// <summary>
        /// Instructs the listener to stop receiving messages.
        /// </summary>
        public virtual bool StopReceiving
        {
            get { return this.stopReceiving; }
            set { this.stopReceiving = value; }
        }

        /// <summary>
        /// Start receiving the message(s) from the queue.
        /// The messages will be taken from the queue until the queue is empty.
        /// This method is triggered every x seconds. (x is defined in application 

configuration file)
        /// </summary>
        public virtual void CheckForMessages()
        {
            try
            {
                ReceiveQueuedMessages();
            }
            catch (MessageQueueException qex)
            {
                string errorMsg = LogMessageQueueException(qex.MessageQueueErrorCode, qex);
                throw new LoggingException(errorMsg, qex);
            }
            catch (LoggingException)
            {
                throw;
            }
            catch (Exception ex)
            {
                string errorMsg = string.Format(Resources.Culture, 

Resources.MsmqReceiveGeneralError, msmqPath);
                this.eventLogger.LogServiceFailure(
                    errorMsg,
                    ex,
                    TraceEventType.Error);

                throw new LoggingException(errorMsg, ex);
            }
            finally
            {
                this.isCompleted = true;
            }
        }

        /// <summary>
        /// This method supports the Enterprise Library infrastructure and is not intended 

to be used directly from your code.
        /// </summary>
        /// <param name="code">The error code.</param>
        /// <param name="e">The exception, or null.</param>
        /// <returns>The logged message.</returns>
        protected string LogMessageQueueException(MessageQueueErrorCode code, Exception e)
        {
            TraceEventType logType = TraceEventType.Error;
            string errorMsg = string.Empty;

            if (code == MessageQueueErrorCode.TransactionUsage)
            {
                errorMsg = string.Format(Resources.Culture, 

Resources.MsmqInvalidTransactionUsage, msmqPath);
            }
            else if (code == MessageQueueErrorCode.IOTimeout)
            {
                errorMsg = string.Format(Resources.Culture, Resources.MsmqReceiveTimeout, 

msmqPath);
                logType = TraceEventType.Warning;
            }
            else if (code == MessageQueueErrorCode.AccessDenied)
            {
                errorMsg = string.Format(Resources.Culture, Resources.MsmqAccessDenied, 

msmqPath, WindowsIdentity.GetCurrent().Name);
            }
            else
            {
                errorMsg = string.Format(Resources.Culture, Resources.MsmqReceiveError, 

msmqPath);
            }

            this.eventLogger.LogServiceFailure(
                errorMsg,
                e,
                logType);

            return errorMsg;
        }

        private MessageQueue CreateMessageQueue()
        {
            MessageQueue messageQueue = new MessageQueue(msmqPath, false, true);
            ((XmlMessageFormatter)messageQueue.Formatter).TargetTypeNames = new string[] { 

"System.String" };
            return messageQueue;
        }

        private bool IsQueueEmpty()
        {
            bool empty = false;
            try
            {
                using (MessageQueue msmq = CreateMessageQueue())
                {
                    msmq.Peek(new TimeSpan(0));
                }
            }
            catch (MessageQueueException e)
            {
                if (e.MessageQueueErrorCode == MessageQueueErrorCode.IOTimeout)
                {
                    empty = true;
                }
            }

            return empty;
        }

        private void ReceiveQueuedMessages()
        {
            this.isCompleted = false;
            while (!IsQueueEmpty())
            {
                using (MessageQueue msmq = CreateMessageQueue())
                {
                    System.Messaging.Message message = msmq.Peek();

                    string serializedEntry = message.Body.ToString();
                    LogEntry logEntry = new LogEntry();
                    try
                    {
                        logEntry.Message = serializedEntry;
                    }
                    catch (FormatException formatException)
                    {
                        string logMessage = string.Format(
                            Resources.Culture,
                            Resources.ExceptionCouldNotDeserializeMessageFromQueue,
                            message.Id,
                            msmq.Path);

                        this.eventLogger.LogServiceFailure(
                            logMessage,
                            formatException,
                            TraceEventType.Error);

                        throw new LoggingException(logMessage, formatException);
                    }
                    catch (SerializationException serializationException)
                    {
                        string logMessage = string.Format(
                            Resources.Culture,
                            Resources.ExceptionCouldNotDeserializeMessageFromQueue,
                            message.Id,
                            msmq.Path);

                        this.eventLogger.LogServiceFailure(
                            logMessage,
                            serializationException,
                            TraceEventType.Error);

                        throw new LoggingException(logMessage, serializationException);
                    }

                    if (logEntry != null)
                    {
                        msmq.Formatter = new ActiveXMessageFormatter();
                       // 

Microsoft.Practices.EnterpriseLibrary.Logging.Logger.Write(logEntry);
                        logWriter.Write(logEntry);
                        
                       //logEntry.Title = "Consumer Service Log";
                       // logWriter.Write(logEntry);
                    }

                    message = msmq.Receive();

                    if (this.StopReceiving)
                    {
                        this.isCompleted = true;
                        return;
                    }
                }
            }
        }
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Messaging;
using System.ServiceModel;
using System.Configuration;
using System.Xml.Serialization;
using System.Xml;
using System.Web;
using System.Diagnostics;
using Microsoft.Practices.EnterpriseLibrary.Common;
using Microsoft.Practices.EnterpriseLibrary.Data;
using Microsoft.Practices.EnterpriseLibrary.Logging;
using Microsoft.Practices.EnterpriseLibrary.Logging.Database;
using Microsoft.Practices.EnterpriseLibrary.Logging.Configuration;

using DTG.Global.Utility;
using DTG.Global.Object;



namespace WCF_MSMQ.MSMQ
{
    class Program
    {
        [STAThread]


        static void Main(string[] args)
        {
            Console.WriteLine();

            
            ////LogManager.WriteLog("Error in Rate Shop request.",null,LogManager.LogCategory.Error,LogManager.LogPriority.High, 200, System.Diagnostics.TraceEventType.Error,"RateShop", null);
            ////LogManager.WriteLog("Message Test",null, "Error", 1, 2223, "Normal", "No Title", null);
            ////LogManager.WriteLog<String>("Trail Message");

            Microsoft.Practices.EnterpriseLibrary.Logging.LogEntry logEntry = new LogEntry();
            logEntry.EventId = 100;
            logEntry.Priority = 2;
            logEntry.Message = "DISTRIBUTOR TEST";
            logEntry.Brand = "Thrifty";
            logEntry.Farm = "ZTZRBrands";

            DTG.Global.Object.Message message = new DTG.Global.Object.Message(5, "error trying to make a res");
            Exception exceptionMessage = new Exception("Wrong");
            string category = "Information";
            int priority = 50;
            string title = "CSLOG";
            string brand = "ZT";
            string farm = "ZTZR";
            Dictionary<string, object> properties = new Dictionary<string, object>();
            properties.Add("Test String", new Guid());

            //LogManager.Log(message, exceptionMessage, category, priority, TraceEventType.Resume, title, brand, farm);

            Logger.Write(logEntry);
            
          //  Microsoft.Practices.EnterpriseLibrary.Logging.Logger.Write(logEntry);

        }
        }

    }

<?xml version="1.0" encoding="utf-8"?>
<configuration>
	<configSections>
		<section name="loggingConfiguration"
				 type="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.LoggingSettings, Microsoft.Practices.EnterpriseLibrary.Logging" />
		<section name="dataConfiguration"
				 type="Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data" />
	</configSections>
	<loggingConfiguration name="Logging Application Block"
						  tracingEnabled="true"
						  defaultCategory="General"
						  logWarningsWhenNoCategoriesMatch="true">
		<listeners>
			<add name="Formatted EventLog TraceListener"
				 source="Enterprise Library Logging"
				 formatter="Text Formatter"
				 log="Application"
				 machineName="8W-64217"
				 listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.FormattedEventLogTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging"
				 traceOutputOptions="None"
				 filter="All"
				 type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.FormattedEventLogTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging"
         />
			<add name="Msmq TraceListener"
				 type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.MsmqTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging"
				 listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.MsmqTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging"
				 traceOutputOptions="None"
				 filter="All"
				 queuePath="Formatname:DIRECT=OS:8W-64217\private$\anjana"
				 formatter="Text Formatter"
				 messagePriority="Normal"
				 timeToReachQueue="49710.06:28:15"
				 timeToBeReceived="49710.06:28:15"
				 recoverable="false"
				 useAuthentication="false"
				 useDeadLetterQueue="false"
				 useEncryption="false"
				 transactionType="None" />
		</listeners>


		<formatters>
			<add template="Timestamp:  {timestamp}&#xD;&#xA;Message:  {message}&#xD;&#xA;Category:  {category}&#xD;&#xA;Priority:  {priority}&#xD;&#xA;EventId:  {eventid}&#xD;&#xA;Severity:  {severity}&#xD;&#xA;Title:  {title}&#xD;&#xA;Brand:  {brand}&#xD;&#xA;Farm:  {farm}&#xD;&#xA;Machine:  {machine}&#xD;&#xA;Application Domain:  {appDomain}&#xD;&#xA;Process Id:  {processId}&#xD;&#xA;Process Name:  {processName}&#xD;&#xA;Win32 Thread Id:  {win32ThreadId}&#xD;&#xA;Thread Name:  {threadName}&#xD;&#xA;Extended Properties:  {dictionary({key} - {value}&#xD;&#xA;)}"
				 type="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=4.1.0.0, Culture=neutral, PublicKeyToken=null"
				 name="Text Formatter" />
		</formatters>
		<categorySources>
			<add switchValue="All"
				 name="Error">
				<listeners>
					<add name="Msmq TraceListener" />
				</listeners>
			</add>
			<add switchValue="All"
				 name="General">
				<listeners>
					<add name="Msmq TraceListener" />
				</listeners>
			</add>
			<add switchValue="All"
				 name="Information">
				<listeners>
					<add name="Msmq TraceListener" />
				</listeners>
			</add>
		</categorySources>
		<specialSources>
			<allEvents switchValue="All"
					   name="All Events" />
			<notProcessed switchValue="All"
						  name="Unprocessed Category" />
			<errors switchValue="All"
					name="Logging Errors &amp; Warnings">
				<listeners>
					<add name="Formatted EventLog TraceListener" />
					<add name="Msmq TraceListener" />
				</listeners>
			</errors>
		</specialSources>
	</loggingConfiguration>
</configuration>


MSMQLogDistributor.APP.CONFIG 

<?xml version="1.0" encoding="utf-8"?>
<configuration>
	<configSections>
		<section name="loggingConfiguration"
				 type="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.LoggingSettings, Microsoft.Practices.EnterpriseLibrary.Logging" />
		<section name="dataConfiguration"
				 type="Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data " />
		<section name="msmqDistributorSettings"
				 type="DTG.Global.Utility.Logging.LogService.Configuration.MsmqDistributorSettings, ConsumerService_LoggingService" />
	</configSections>
	<loggingConfiguration name="Logging Application Block"
						  tracingEnabled="true"
						  defaultCategory="General"
						  logWarningsWhenNoCategoriesMatch="true">
		<listeners>
			<add databaseInstanceName="LogConnection"
				 writeLogStoredProcName="WriteLog"
				 addCategoryStoredProcName="AddCategory"
				 formatter="Text Formatter"
				 listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Database.Configuration.FormattedDatabaseTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging.Database"
				 traceOutputOptions="None"
				 filter="All"
				 type="Microsoft.Practices.EnterpriseLibrary.Logging.Database.FormattedDatabaseTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging.Database"
				 name="Database Trace Listener" />
		</listeners>
		<formatters>
			<add template="Timestamp:  {timestamp}&#xD;&#xA;Message:  {message}&#xD;&#xA;Category:  {category}&#xD;&#xA;Priority:  {priority}&#xD;&#xA;EventId:  {eventid}&#xD;&#xA;Severity:  {severity}&#xD;&#xA;Title:  {title}&#xD;&#xA;Brand:  {brand}&#xD;&#xA;Farm:  {farm}&#xD;&#xA;Machine:  {machine}&#xD;&#xA;Application Domain:  {appDomain}&#xD;&#xA;Process Id:  {processId}&#xD;&#xA;Process Name:  {processName}&#xD;&#xA;Win32 Thread Id:  {win32ThreadId}&#xD;&#xA;Thread Name:  {threadName}&#xD;&#xA;Extended Properties:  {dictionary({key} - {value}&#xD;&#xA;)}"
				 type="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=4.1.0.0, Culture=neutral, PublicKeyToken=null"
				 name="Text Formatter" />
		</formatters>
		<categorySources>
			<add switchValue="All"
				 name="General">
				<listeners>
					<add name="Database Trace Listener" />
				</listeners>
			</add>
			<add switchValue="All"
				 name="Information">
				<listeners>
					<add name="Database Trace Listener" />
				</listeners>
			</add>
			<add switchValue="All"
				 name="Error">
				<listeners>
					<add name="Database Trace Listener" />
				</listeners>
			</add>
		</categorySources>
		<specialSources>
			<allEvents switchValue="All"
					   name="All Events" />
			<notProcessed switchValue="All"
						  name="Unprocessed Category" />
			<errors switchValue="All"
					name="Logging Errors Warnings">
				<listeners>
					<add name="Database Trace Listener" />
				</listeners>
			</errors>
		</specialSources>
	</loggingConfiguration>
	<connectionStrings>
		<add name="LogConnection"
			 connectionString="Database=Logging;Server=XXXXX\XXXXXX;Integrated Security=SSPI"
			 providerName="System.Data.SqlClient" />
	</connectionStrings>
	<msmqDistributorSettings msmqPath="Formatname:DIRECT=OS:8W-64217\private$\aXXXX"
							 queueTimerInterval="50000"
							 serviceName="Consumer Service Logging Service" />
</configuration>


推荐答案

 

我尝试了一个像您一样的示例,它在我的本地环境中效果很好.我可以正确获取主体字符串.这是我完整的代码:

 

使用 使用 使用 使用 使用 使用 使用 使用  

命名空间 {

公共 部分 class Form3 : Form

    public partial class Form3 : Form

    {

公共 Form3()

        public Form3()

        {

            InitializeComponent();

        }

MessageQueue mq;

        MessageQueue mq;

私有 void Form3_Load(对象发送者, EventArgs e)

        private void Form3_Load(object sender, EventArgs e)

        {

字符串 strDestQ = @.\ private

            string strDestQ = @".\private


\ bian' ; ;
\bian";

 

尝试

            try

            {

//根据需要创建队列

                //create the queue if needed

如果(! MessageQueue .Exists(strDestQ))

                if (!MessageQueue.Exists(strDestQ))

消息框.Show(strDestQ + 不存在" );

                    MessageBox.Show(strDestQ + " doesn't exist");

 

MessageQueue (strDestQ);

                mq = new MessageQueue(strDestQ);

System.Messaging. XmlMessageFormatter (类型 [] { string )});

                mq.Formatter = new System.Messaging.XmlMessageFormatter(new Type[] { typeof(string) });

//构建消息

                //build message

消息 m = System.Messaging.

                System.Messaging.Message m = new System.Messaging.Message();

"Hello World" ;

                m.Label = "Hello World";

 

 

"hi david"; ;

                m.Body = "hi david";

//发送并关闭队列

                // send and close queue

                mq.Send(m);

消息框.Show(&消息已发送!" );

                MessageBox.Show("Message sent!");              

 

            }

捕获(异常例如)

            catch (Exception ex)

            {

消息框 .Show(ex.ToString());

                MessageBox.Show(ex.ToString());

            }

 

        }

私有 bool IsQueueEmpty()

        private bool IsQueueEmpty()

        {

布尔 empty = false ;

            bool empty = false;

尝试

            try

            {

TimeSpan (0));

                mq.Peek(new TimeSpan(0));

            }

捕获( MessageQueueException e)

            catch (MessageQueueException e)

            {

如果(例如,MessageQueueErrorCode == MessageQueueErrorCode .IOTimeout)

                if (e.MessageQueueErrorCode == MessageQueueErrorCode.IOTimeout)

                {

true ;

                    empty = true;

                }

            }

 

返回为空;

            return empty;

        }

 

 

私有 void button1_Click(对象发送者, EventArgs e)

        private void button1_Click(object sender, EventArgs e)

        {

同时(!IsQueueEmpty())

            while (!IsQueueEmpty())

            {

消息 messageReceived = System.Messaging.

                System.Messaging.Message messageReceived = new System.Messaging.Message();

 

                messageReceived = mq.Peek();

 

字符串 body = messageReceived.Body.ToString();

                string body = messageReceived.Body.ToString();

 

消息框 .Show(body);

                MessageBox.Show(body);

 

                messageReceived = mq.Receive();

            }

        }

    }

}

 

看来您的代码是正确的,我建议您逐行调试,然后检测哪个行代码引起了原因.您也可以尝试我的代码. By the way, I would like to point out a code problem in your code, see following code:

 

using (MessageQueue msmq = CreateMessageQueue())

 

This line code will run in every loop, this will cause bad performance. We can create a global MessageQueue variable.

 

 

If I misunderstood your question, please let me know and provide detailed explanation. Thanks.

 

 

Best regards,
Guang-Ming Bian - MSFT
MSDN Subscriber Support in Forum
If you have any feedback on our support, please contact msdnmg@microsoft.com

 


这篇关于使用MSMQ的格式化程序出现问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆