Using message queues for outbound calls
Many of you familiar with Microsoft Speech Server/Office Communications Server are likely aware that the preferred way to place outbound calls is through a message queue. I spent some time looking through our documentation and noticed that we have a decent amount of info on how to setup your message queue, but few details on how to write an application that makes use of one.
For those of you not familiar with message queues, the best place for information is MSDN. Start with the MessageQueue and Message objects and move to the bottom of the articles for other suggested pages. I will not cover how to open and write to message queues here as there are numerous examples on the web already for this. Basically the way it works is you place messages in a queue through an application or service that you write and Speech Server reads the messages from the queue and uses them to place calls.
Since any outbound call triggered is really just an HTTP request, you might wonder why it is better to let Speech Server manage calls this way rather than just placing HTTP requests yourself. MSS does a number of things for you here. For one, you can set the maximum number of outbound calls that can be made at one time and we will not pull messages from the queue if there are no available channels. If the queue becomes unavailable at any time (perhaps it is on a remote machine that has been powered down), we will keep retrying every ten seconds. We also save you a good deal of coding.
There are two limitations of the message queue capabilities of Speech Server that I must call out here. The first is that, though you can have multiple applications running on the same machine each listening to a different queue, no two applications may listen to the same queue. If you really need to do something like this, you will need to create a 'driver' application that receives the messages and transfers the call to the appropriate application.
The second limitation (or 'feature') is that if the call is not answered, not reachable, or busy you must place the message back on the queue yourself. It will not be replaced automatically. If you are unsure how to detect whether a call is in one of these states, see the outbound call and outbound call custom activity sample applications that ship with MSS. Note that the outbound call workflow sample makes use of a message queue, which is one reason why I did not include sample code here. This sample code shows how to place a message in the queue and how to programmatically determine the message queue assigned to the current application.
Setting up a queue for MSS is in the documentation but if you are lazy like myself there are three main things you need to do.
1) Create the queue. The queue can be remote or local and public or private. In general a local queue will give you the best performance for obvious reasons. See the message queue documentation for the differences between the different types of queues.
2) On Windows Server 2003, make sure the Network Service account has access to the queue. On XP (for debugging purposes only), make sure the ASP.Net account has access to the queue.
3) Specify the queue for the application by right clicking on the application in the Administration Console and selecting properties.
The last question you probably have is how to make use of the contents of the message to determine what to do for the outbound call (such as who you should call). There are two ways you can do this.
1) The body of the message is deserialized to a string by MSS and added to the application URL. So, if you add a message with the body "OutboundPhoneNumber=5551212", you can retrieve the phone number by reading the query string using code similar to the following
outboundNumber = Uri.UnescapeDataString(QueryString["OutboundPhoneNumber"]);
2) The Message object itself is accessible using the MsmqMessage property of the IApplicationHost object. This is particularly useful if you subclassed the Message object to create your own message information.