Wednesday, June 29, 2011

Inconvenient Convenience: Accessing the Outgoing MSMQ Queue in a C# WCF Service Application

To start things off, I had an issue with with a Client/Server application that I was debugging for the company I am working for. It was a project that was twice handed down and had turned into a bit of a "Frankenstein" project.

Anyway, the issue I was attempting to find a solution for was when the the Internet connection would go down and the Client would just keep on locally queuing messages to the remote server. Once the Internet connection came back on, all the messages would be transferred to the server and be processed. To some this might not seem a huge issue however the Internet is provided through a $/MB 3G cellular connection and so efficient data transfer was paramount.

The solution was simply to look if there was a message already queued in the Outgoing MSMQ queue before attempting to queue. It took a bit, but with help from the references below, the implementation looked like:


public int GetQueueLength()
{

string queueFormatName = @"FORMATNAME:DIRECT=TCP:10.10.10.10\private$\queuename";
int outgoingQueueLength = 0;
MessageQueue sourceQueue = new MessageQueue(queueFormatName, QueueAccessMode.ReceiveAndAdmin);

sourceQueue.Formatter = new XmlMessageFormatter(new Type[] {typeof(string)});

outgoingQueueLength = GetMessageCount(sourceQueue);

return outgoingQueueLength;
}

private Message PeekWithoutTimeout(MessageQueue queue, Cursor cursor, PeekAction action)
{
Message result = null;

try
{
result = queue.Peek(new TimeSpan(1), cursor, action);
}
catch (MessageQueueException mqe)
{
Console.WriteLine(mqe.Message);
}

return result;
}

private int GetMessageCount(MessageQueue queue)
{
int count = 0;
Cursor cursor = queue.CreateCursor();

Message message = PeekWithoutTimeout(queue, cursor, PeekAction.Current);

if (message != null)
{
count = 1;
while ((message = PeekWithoutTimeout(queue, cursor, PeekAction.Next)) != null)
{
count++;
}
}

return count;
}



Note 1: 10.10.10.10 would be the address to the remote server. and queuename is the exact queue name specified. For example, another one would be: "FORMATNAME:DIRECT=TCP:172.16.1.1\private$\project1/app2".

project1/app2 would be the queuename in this instance.

Note 2: MSMQ and VPN's don't play nice, see directly below link. I set my MSMQ to be Automatic (Delayed) as to wait for the VPN to come up before starting.

http://mrnye.blogspot.com/2010/02/msmq-over-vpn-connection.html

References:
http://www.yortondotnet.com/2010/04/accessing-outgoing-message-queues-with.html

http://jopinblog.wordpress.com/2008/03/12/counting-messages-in-an-msmq-messagequeue-from-c/

Friday, April 29, 2011

Emailing from a C# application

For an application I am working on I needed to create a .NET web service for emailing out using Gmail's free smtp server. So I created a generic email connector and will input Gmail's server: smtp.gmail.com port: 587 for sending emails.