Software Requirements
- Visual Studio 2008 (Also works in 2005, but not tested for this tutorial.)
- MSMQ Installed and Running. To Implement Security MSMQ installation must be integrated to AD.
- .NET 3.0 Framework or higher
- IIS
- Distributed Transaction Coordinator (DTC) Must be installed and running.
The Goal here is to setup an asynchronous communication between a client and server using WCF and MSMQ. To do that I use a “WCFQ” solution which contains 3 projects.
The Goal here is to setup an asynchronous communication between a client and server using WCF and MSMQ. To do that I use a “WCFQ” solution which contains 3 projects.
- WCFQ.Service – Hosts Queued WCF Service.
- WCFQ.Contract – Contains the Data and Service contracts for the Queued WCF Service.
- WCFQ.Client – A Console application to call WCFQ.Service
Step 1: Open Visual Studio 2008 IDE and Create a “WCF Service Application”
Step 2: Add another “Class Library” Project and Delete “Class1.cs” from the project.
Step 3: Delete IService1.cs in WCFQ.Service and add IService1.cs to WCFQ.Contract and replace the code with below. The trick here is when building WCF-MSMQ services is to ensure that all the operation contracts are defined with IsOneWay=true.
using System;
using System.Runtime.Serialization;
using System.ServiceModel;
namespace WCFQ.Contract
{
[ServiceContract]
public interface IService1
{
[OperationContract(IsOneWay=true)]
void SendData(QData composite);
}
//An object for Data Contract
[DataContract]
public class QData
{
[DataMember]
public string Name { get; set; }
}
}
Step 4: Add references of “System.ServiceModel” and “System.Runtime.Serialization” to WCFQ.Contract. This is where you define the contract.
Step 5: Reference WCFQ.Contract project in WCFQ.Service and change the Service1.svc.cs code should look like this.
using System;
using System.Diagnostics;
using WCFQ.Contract;
namespace WCFQ.Service
{
public class Service1 : IService1
{
public void SendData(QData qdata)
{
//Do something with the data
Trace.WriteLine(String.Format("Name : {0}", qdata.Name));
}
}
}
Step 6: Now, The configuration comes into picture. Here is how the ServiceModel part of web.config should look like. We don’t need wsHttpBinding to get net MSMQ to be working. That is default and I left it that way to make it easy to understand the WCF Service is working.
<SYSTEM.SERVICEMODEL>
<BINDINGS>
<NETMSMQBINDING>
<BINDING name="WCFQNonTransactional" exactlyonce="false">
<SECURITY mode="None" />
</BINDING>
</NETMSMQBINDING>
</BINDINGS>
<SERVICES>
<SERVICE name="WCFQ.Service.Service1" behaviorconfiguration="WCFQ.Service.Service1Behavior">
<ENDPOINT contract="WCFQ.Contract.IService1" binding="wsHttpBinding" address="http://localhost/WCFQService/Service1.svc">
<IDENTITY>
<DNS value="localhost" />
</IDENTITY>
</ENDPOINT>
<ENDPOINT contract="WCFQ.Contract.IService1" binding="netMsmqBinding" address="net.msmq://localhost/private/WCFQService/Service1.svc" bindingconfiguration="WCFQNonTransactional" />
</SERVICE>
</SERVICES>
<BEHAVIORS>
<SERVICEBEHAVIORS>
<BEHAVIOR name="WCFQ.Service.Service1Behavior">
<SERVICEMETADATA httpgetenabled="true" />
<SERVICEDEBUG includeexceptiondetailinfaults="false" />
</BEHAVIOR>
</SERVICEBEHAVIORS>
</BEHAVIORS>
</SYSTEM.SERVICEMODEL>
Step 7: The WCF service to work with MSMQ there is one more rule. That is the queue name which must be same as the URI that is used to Access the WCF Service. So, if the URL is http://localhost/WCFQService/Service1.svc, then the Queue Name will be “WCFQService/Service1.svc”. This has to be created manually by going to “Computer Management/Services and Applications/Message Queuing/Private Queues”. When creating the Queue, Do not check “Transactional”. Computer Management can be accessed from Right click on My Computer and click on Manage or “Start -> Run” and typing “Compmgmt.msc” and Hit enter.
Step 8: After creating the queue, enable Journal by Right click and select properties on the queue. Check the Enabled checkbox inside Journal Area. This is just for tracking purpose that your messages reached MSMQ. Next go to security tab of the properties and Add user “Network Service” and give full control to the user. This is the user who writes and reads out messages from the queue.
Step 9: Configure the WCFQ.Service to Run in IIS by setting the project properties. Remove the DOT from the WCFQ.Service and Create virtual directory. [Note: Windows 7 or Windows 2008 server must create an application pool which runs with “Network service” User, instead of “ApplicationPoolIdentity” and assign the application pool create to the WCFQService from IIS, INetMgr]
Step 10: In order to make the WCF to work with MSMQ we need to enable MSMQ WAS listener on the WCFQService application that is just created by running following command from command prompt from location C:\Windows\System32\inetsrv.
appcmd set app "Default web site/WCFQService" /enabledProtocols:net.msmq,http
This enables the net.msmq protocol on WCFQService application on IIS.
Step 11: Now, The WCFQService application is ready to roll. So, let’s get to the client. Add a Console Application to the project. And add references for WCFQ.Contract project, System.ServiceModel.
Step 12: Without having to create a proxy and access the WCF service, Add a new class called “WCFQService1Client.cs”. The proxy class derives from the class ClientBase<T>. ClientBase<T> accepts a single generic type parameter identifying the service contract that this proxy encapsulates. The Channel property of ClientBase<T> is of the type of that type parameter. The generated subclass of ClientBase<T> simply delegates to Channel the method call.
using System;
using System.ServiceModel;
using WCFQ.Contract;
namespace WCFQ.Client
{
internal class WCFQService1Client : ClientBase, IService1
{
public WCFQService1Client(string endpoint) : base(endpoint)
{
}
//IService1 Members
public void SendData(QData data)
{
Channel.SendData(data);
}
}
}
Step 13: Now configure the Client app.config to access the WCF Service.
<?xml version="1.0" encoding="utf-8"?>
<CONFIGURATION>
<SYSTEM.SERVICEMODEL>
<BINDINGS>
<NETMSMQBINDING>
<BINDING name="WCFQNonTransactional" exactlyonce="false">
<SECURITY mode="None" />
</BINDING>
</NETMSMQBINDING>
<WSHTTPBINDING>
<BINDING name="WCFQwsHttp">
<SECURITY mode="None" />
</BINDING>
</WSHTTPBINDING>
</BINDINGS>
<CLIENT>
<ENDPOINT name="WCFQNonTransactional" contract="WCFQ.Contract.IService1" binding="netMsmqBinding" address="net.msmq://localhost/private/WCFQService/Service1.svc" bindingconfiguration="WCFQNonTransactional" />
<ENDPOINT name="WCFQwsHttp" contract="WCFQ.Contract.IService1" binding="wsHttpBinding" address="http://localhost/WCFQService/Service1.svc" bindingconfiguration="WCFQwsHttp" />
</CLIENT>
</SYSTEM.SERVICEMODEL>
</CONFIGURATION>
Step 13: To use the proxy, the client first needs to instantiate a proxy object and provide the constructor with endpoint information from the endpoint section name from the config file. The client can then use the proxy methods to call the service, and when the client is done, the client needs to close the proxy instance. The program.cs will look like this after implementing the code.
using System;
using WCFQ.Contract;
namespace WCFQ.Client
{
class Program
{
static void Main(string[] args)
{
QData data = new QData();
data.Message = "Hello World!";
//Send Message
using (WCFQService1Client proxy = new WCFQService1Client("WCFQNonTransactional"))
{
Console.WriteLine("Sending Message {0} ", data.Message);
proxy.SendData(data);
//Close the client.
proxy.Close();
}//Dispose
Console.Read();
}
}
}
Step 14: Set WCFQ.Client as the startup project and run……. Here is what needs to be observed to make sure the service and client ran fine.
Command window of client will show
MSMQ Window will show the journal message count increased by 1.
Next time I will post on working with transactional messaging.
Click hear to Download source code here…