Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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
You can’t perform that action at this time.