Benutzer:MovGP0/NET/MSMQ

aus Wikipedia, der freien Enzyklopädie
Zur Navigation springen Zur Suche springen
   MovGP0        Über mich        Hilfen        Artikel        Weblinks        Literatur        Zitate        Notizen        Programmierung        MSCert        Physik      

Achtung: Beispiel unterstützt keine Transaktion; Nachricht geht bei Exception verloren

using System;
using System.Messaging;

namespace PipesAndFilters
{
	public class Processor
	{
		protected MessageQueue _inputQueue;
		protected MessageQueue _outputQueue;

		public Processor(MessageQueue inputQueue,MessageQueue outputQueue)
		{
			_inputQueue = inputQueue;
			_outputQueue = outputQueue;
		}

		public void Process()
		{
			_inputQueue.ReceiveCompleted += new ReceiveCompletedEventHandler(OnReceiveCompleted);
			_inputQueue.BeginReceive();
		}

		private void OnReceiveCompleted(object source, ReceiveCompletedEventArgs asyncResult)
		{
			var messageQueue = (MessageQueue)source;
			var inputMessage = messageQueue.EndReceive(asyncResult.AsyncResult);
			inputMessage.Formatter = new XmlMessageFormatter(new string[] { "System.String,mscorlib" });
			var outputMessage = ProcessMessage(inputMessage);
			outputQueue.Send(outputMessage);
			messageQueue.BeginReceive();
		}

		protected virtual Message ProcessMessage(Message message)
		{
			Console.WriteLine("Received Message: {0}", message.Body);
			return message;
		}
	}
}

One-To-Many Messaging[1]

[Bearbeiten | Quelltext bearbeiten]
  • requires MSMQ 3.0+
Multicast addresses
Distribution Lists
Multiple-Element Formal Names
  • Sender sendet eine Message zu einer Liste von Empfängern
  • Verstößt gegen das Publish-Subscribe-Pattern, da der Sender (statt Empfänger) bestimmt wohin die Nachricht geht
  • kein Support in .NET. Wrapper für Message Queuing COM Components nötig.

Persistant Messages

[Bearbeiten | Quelltext bearbeiten]

enable transactional persistance to disk to avoid data loss

var queue = MessageQueue.Create(@".\MyQueueName", true);
Service
public partial class MyService : ServiceBase
{
  private ServiceHost host;

  public MyService()
  {
    InitializeComponent();
  }

  protected override void OnStart(string[] args)
  {
    string queueName = ConfigurationManager.AppSettings["ProcessMsgQueueName"];
    if (!MessageQueue.Exists(queueName))
    {
      MessageQueue thisQueue = MessageQueue.Create(queueName, true);
      thisQueue.SetPermissions("Everyone", MessageQueueAccessRights.ReceiveMessage);
    }

    try
    {
      Uri serviceUri = new Uri("msmq.formatname:DIRECT=OS:" + queueName);

      // communicate to MSMQ how to transfer and deliver the messages
      MsmqIntegrationBinding serviceBinding = new MsmqIntegrationBinding();
      serviceBinding.Security.Transport.MsmqAuthenticationMode = MsmqAuthenticationMode.None;
      serviceBinding.Security.Transport.MsmqProtectionLevel = System.Net.Security.ProtectionLevel.None;

      serviceBinding.SerializationFormat = MsmqMessageSerializationFormat.Binary;

      host = new ServiceHost(typeof(MyService.Service1)); // add watcher class name
      host.AddServiceEndpoint(typeof(MyService.IService1), serviceBinding, serviceUri);
      host.Open();
    }
    catch (Exception ex)
    {
      EventLog.WriteEntry("SERVICE" + ex.Message, EventLogEntryType.Error);
    }
  }

  protected override void OnStop()
  {
    if (host != null)
     host.Close();
  }
}
Contract
[ServiceContract(Namespace = "MyService")]
[ServiceKnownType(typeof(Events.Dashboard_Message))]
public interface IService1
{
  [OperationContract(IsOneWay = true, Action="*")]
  void ProcessMSMQMessage(MsmqMessage<Events.Dashboard_Message> msg);
}
Class
public class Service1 : IService1
{
  [OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]
  public void ProcessMSMQMessage(MsmqMessage<Events.Dashboard_Message> msg)
  {
    string msgName = msg.GetType().Name;

    // send to eventlog
    EventLog.WriteEntry("MyService", msgName);  
  }
}

Internet Information Service (IIS)

[Bearbeiten | Quelltext bearbeiten]
Server
  • configure Auto-Start[2]
<system.serviceModel>
   <services>
      <service name="MyProject.Web.Services.EmsListener">
         <endpoint address="net.msmq://localhost/private/myQueue"
                   binding="netMsmqBinding" bindingConfiguration="MyMsmqBinding"
                   contract="MyProject.Abstraction.IEmsListener">
         </endpoint>
         <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
      </service>
   </services>
   <netMsmqBinding >
      <binding name="MyMsmqBinding"
               durable="true"
               receiveRetryCount="2"
               maxRetryCycles="2"
               retryCycleDelay="00:01:00"
               receiveErrorHandling="Move" >
      <security mode="None">
         <message clientCredentialType="None"/>
         <transport msmqAuthenticationMode="None" msmqProtectionLevel="None"  />
      </security>
   </binding>
</netMsmqBinding>
Client
<system.serviceModel>
   <bindings>
      <netMsmqBinding>
         <binding name="MyBinding ">
            <security mode="None" />
         </binding>
      </netMsmqBinding>
   </bindings>
   <client>        
      <endpoint address="net.msmq://localhost/private/myQueue" binding="netMsmqBinding"
                bindingConfiguration=" MyBinding " contract="EmsListener.IEmsListener"
                name=" MyBinding " />
   </client>
</system.serviceModel>

Message Envelope

[Bearbeiten | Quelltext bearbeiten]

might have

  • GUID (for duplicate identification)
  • DateTime of creation
  • DateTime of expiration
  • address from sender
  • address of recipient
  1. Multiple-Destination Messaging. In: MSDN. Microsoft, abgerufen am 12. Juni 2014 (englisch).
  2. Auto-Start Feature. In: MSDN. Microsoft, abgerufen am 3. Juli 2014 (englisch).