Skip to content

Instantly share code, notes, and snippets.

@mfcollins3
Created September 20, 2012 17:54
Show Gist options
  • Save mfcollins3/3757366 to your computer and use it in GitHub Desktop.
Save mfcollins3/3757366 to your computer and use it in GitHub Desktop.
This Gist demonstrates how to use WCF with MSMQ to handle dead letters or poison messages.
namespace Client
{
using System;
using System.ServiceModel;
using Contracts;
internal class ClientProgram
{
public static void Main(string[] args)
{
ChannelFactory<ISayHelloService> channelFactory = null;
ISayHelloService service = null;
ServiceHost deadLetterServiceHost = null;
try
{
#if false
// Just for reference purposes, you can use this code if you
// want messages to go to the system's dead letter queue.
var netMsmqBinding = new NetMsmqBinding(NetMsmqSecurityMode.None)
{ DeadLetterQueue = DeadLetterQueue.System, TimeToLive = TimeSpan.FromSeconds(20.0) };
#else
var netMsmqBinding = new NetMsmqBinding(NetMsmqSecurityMode.None)
{
DeadLetterQueue = DeadLetterQueue.Custom,
CustomDeadLetterQueue = new Uri("net.msmq://localhost/private/wcftestdeadletter"),
TimeToLive = TimeSpan.FromMinutes(2.0)
};
#endif
var remoteAddress = new EndpointAddress("net.msmq://localhost/private/wcftest");
channelFactory = new ChannelFactory<ISayHelloService>(netMsmqBinding, remoteAddress);
channelFactory.Open();
var baseAddress = new Uri("net.msmq://localhost/private");
deadLetterServiceHost = new ServiceHost(typeof(SayHelloDeadLetterService), baseAddress);
netMsmqBinding = new NetMsmqBinding(NetMsmqSecurityMode.None);
deadLetterServiceHost.AddServiceEndpoint(typeof(ISayHelloService), netMsmqBinding, "/wcftestdeadletter");
deadLetterServiceHost.Open();
service = channelFactory.CreateChannel();
var clientChannel = service as IClientChannel;
if (CommunicationState.Opened != clientChannel.State)
{
clientChannel.Open();
}
Console.Error.WriteLine("Enter a name to send. Enter a blank line to exit.");
while (true)
{
var name = Console.ReadLine();
if (string.IsNullOrWhiteSpace(name))
{
break;
}
service.SayHello(name);
}
}
finally
{
var clientChannel = service as IClientChannel;
if (null != clientChannel && CommunicationState.Opened == clientChannel.State)
{
clientChannel.Close();
clientChannel.Dispose();
}
if (null != channelFactory && CommunicationState.Opened == channelFactory.State)
{
channelFactory.Close();
}
if (null != deadLetterServiceHost && CommunicationState.Opened == deadLetterServiceHost.State)
{
deadLetterServiceHost.Close();
}
}
}
}
}
namespace Contracts
{
using System.ServiceModel;
[ServiceContract]
public interface ISayHelloService
{
[OperationContract(IsOneWay = true)]
void SayHello(string to);
}
}
namespace Client
{
using System;
using System.ServiceModel;
using Contracts;
[ServiceBehavior(AddressFilterMode = AddressFilterMode.Any)]
internal class SayHelloDeadLetterService : ISayHelloService
{
public void SayHello(string to)
{
Console.Error.WriteLine("DEAD LETTER: {0}", to);
}
}
}
namespace Service
{
using System;
using System.ServiceModel;
using Contracts;
[ServiceBehavior(AddressFilterMode = AddressFilterMode.Any)]
internal class SayHelloPoisonMessageService : ISayHelloService
{
[OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]
public void SayHello(string to)
{
Console.Error.WriteLine("POISON MESSAGE: {0}", to);
}
}
}
namespace Service
{
using System;
using System.ServiceModel;
using Contracts;
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
internal class SayHelloService : ISayHelloService
{
[OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]
public void SayHello(string to)
{
if (to.Equals("john", StringComparison.OrdinalIgnoreCase))
{
Console.Error.WriteLine("ERROR: John is not welcome.");
throw new Exception("John is not welcome.");
}
Console.Out.WriteLine("Hello, {0}!", to);
}
}
}
namespace Service
{
using System;
using System.ServiceModel;
using Contracts;
internal class ServiceProgram
{
public static void Main(string[] args)
{
ServiceHost serviceHost = null;
ServiceHost poisonMessageHost = null;
try
{
var baseAddress = new Uri("net.msmq://localhost/private");
serviceHost = new ServiceHost(typeof(SayHelloService), baseAddress);
var netMsmqBinding = new NetMsmqBinding(NetMsmqSecurityMode.None)
{
ReceiveRetryCount = 1,
ReceiveErrorHandling = ReceiveErrorHandling.Move,
MaxRetryCycles = 1,
RetryCycleDelay = TimeSpan.FromSeconds(10.0)
};
serviceHost.AddServiceEndpoint(typeof(ISayHelloService), netMsmqBinding, "/wcftest");
serviceHost.Open();
poisonMessageHost = new ServiceHost(typeof(SayHelloPoisonMessageService));
netMsmqBinding = new NetMsmqBinding(NetMsmqSecurityMode.None);
poisonMessageHost.AddServiceEndpoint(
typeof(ISayHelloService), netMsmqBinding, new Uri("net.msmq://localhost/private/wcftest;poison"));
poisonMessageHost.Open();
Console.Error.WriteLine("The service is listening for requests. Press Enter to exit.");
Console.In.ReadLine();
}
catch (Exception ex)
{
Console.Error.WriteLine("\n{0}\n\nPress Enter to exit.", ex);
Console.In.ReadLine();
}
finally
{
if (null != serviceHost && CommunicationState.Opened == serviceHost.State)
{
serviceHost.Close();
}
if (null != poisonMessageHost && CommunicationState.Opened == poisonMessageHost.State)
{
poisonMessageHost.Close();
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment