Suggested Videos
Part 31 - WAS hosting in WCF
Part 32 - Message Exchange Patterns in WCF
Part 33 - OneWay Message Exchange Pattern in WCF
In this video we will discuss, the duplex Message Exchange Pattern in WCF.
Duplex messaging pattern can be implemented using Request/Reply or OneWay operations. We discussed Request/Reply messaging pattern in Part 32, and OneWay messaging pattern in Part 33. First we will discuss implementing duplex messaging pattern using Request/Reply operations. We will then modify the example to implement duplex messaging pattern using oneway operations.
Steps to implement duplex messaging pattern
Step 1: Create a class library project with name = Report Service. Delete the autogenerated class1.cs file and app.config file.
Step 2: Right click on ReportService project in solution explorer and add a WCF service with name = ReportService.
Step 3: Copy and paste the following code in IReportService.cs file
Step 4: Copy and paste the following code in ReportService.cs file
Step 5: Right click on ReportService solution in solution explorer and add a console project with name = Host. We will use this project to host the WCF service.
Step 6: Right click on References folder under Host project and add a reference to ReportService project and System.ServiceModel assembly.
Step 7: Right click on Host project and add Application Configuration file. This should add App.config file.
Step 8: Copy and paste the following configuration in App.config file
Step 9: Copy and paste the following code in Program.cs file in the Host project.
Step 10: Set Host project as the startup project and run the application by pressing CTRL + F5 key. At this point we have the WCF service up and running.
Step 11: Now let's create a client for the WCF service. Create a new windows forms application with name = DuplexClient
Step 12: Add a service reference to ReportService. Right click on References folder and select Add Service Reference. In the Add Service Reference window type Address = http://localhost:8080/ and click GO button. This should bring up the ReportService. In the Namespace textbox type ReportService and click OK. Also add a reference to System.ServiceModel assembly.
Step 13: Design Form1 as shown below, with a button and a textbox controls. Set the following properties on button1
Name = btnProcessReport
Text = Process Report
Step 14: Double click on the button to generate the "click event handler" method. Copy and paste the following code in Form1.cs file.
Step 15: Run client the application by pressing CTRL + F5 and click on "Process Report" button. At this point we will get the following exception.
This operation would deadlock because the reply cannot be received until the current Message completes processing. If you want to allow out-of-order message processing, specify ConcurrencyMode of Reentrant or Multiple on ServiceBehaviorAttribute.
Step 16: To fix the above error, we need to do 2 things
a) In ReportService.cs file, set ConcurrencyMode to Reentrant as shown below.
[ServiceBehavior(ConcurrencyMode=ConcurrencyMode.Reentrant)]
public class ReportService : IReportService
b) In Form1.cs file in DuplexClient project, set UseSynchronizationContext to false as shown below.
[CallbackBehavior(UseSynchronizationContext = false)]
public partial class Form1 : Form, ReportService.IReportServiceCallback
At this point run the service. Update the service reference in the DuplexClient project. Finally run the client project and click Process Report button. So, we have just seen how to implement Duplex messaging pattern using Request/Reply operations.
Now, let's discuss implementing Duplex messaging pattern using OneWay operations.
Step 1: Remove ServiceBehavior attribute that sets ConcurrencyMode to Reentrant from ReportService.cs file
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant)]
public class ReportService : IReportService
Step 2: Remove CallbackBehavior attribute that sets UseSynchronizationContext to false from Form1.cs file in DuplexClient project.
[CallbackBehavior(UseSynchronizationContext = false)]
public partial class Form1 : Form, ReportService.IReportServiceCallback
Step 3: Set ProcessReport() and Progress() operation contracts to OneWay in IReportService.cs file in ReportService project
At the point run the service. Update the service reference in the DuplexClient project. Finally run the client project and click Process Report button. With these changes we are now using Duplex messaging pattern using OneWay operations.
Part 31 - WAS hosting in WCF
Part 32 - Message Exchange Patterns in WCF
Part 33 - OneWay Message Exchange Pattern in WCF
In this video we will discuss, the duplex Message Exchange Pattern in WCF.
Duplex messaging pattern can be implemented using Request/Reply or OneWay operations. We discussed Request/Reply messaging pattern in Part 32, and OneWay messaging pattern in Part 33. First we will discuss implementing duplex messaging pattern using Request/Reply operations. We will then modify the example to implement duplex messaging pattern using oneway operations.
Steps to implement duplex messaging pattern
Step 1: Create a class library project with name = Report Service. Delete the autogenerated class1.cs file and app.config file.
Step 2: Right click on ReportService project in solution explorer and add a WCF service with name = ReportService.
Step 3: Copy and paste the following code in IReportService.cs file
using System.ServiceModel;
namespace ReportService
{
// Associate callback contract with service contract using CallbackContract attribute
[ServiceContract(CallbackContract = typeof(IReportServiceCallback))]
public interface IReportService
{
// Since we have not set IsOnway=true, the operation is Request/Reply operation
[OperationContract]
void ProcessReport();
}
// This is the callback contract
public interface IReportServiceCallback
{
// Since we have not set IsOnway=true, the operation is Request/Reply operation
[OperationContract]
void Progress(int percentageComplete);
}
}Step 4: Copy and paste the following code in ReportService.cs file
using System.ServiceModel;
using System.Threading;
namespace ReportService
{
public class ReportService : IReportService
{
public void ProcessReport()
{
for (int i = 1; i <= 100; i++)
{
// some logic to process the report
Thread.Sleep(100);
// Get the callback channel to send messages to the client
OperationContext.Current.
GetCallbackChannel<IReportServiceCallback>().Progress(i);
}
}
}
}Step 5: Right click on ReportService solution in solution explorer and add a console project with name = Host. We will use this project to host the WCF service.
Step 6: Right click on References folder under Host project and add a reference to ReportService project and System.ServiceModel assembly.
Step 7: Right click on Host project and add Application Configuration file. This should add App.config file.
Step 8: Copy and paste the following configuration in App.config file
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="mexBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="mexBehavior" name="ReportService.ReportService">
<endpoint address="ReportService" binding="netTcpBinding" bindingConfiguration=""
contract="ReportService.IReportService" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8080" />
<add baseAddress="net.tcp://localhost:8090" />
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
</configuration>Step 9: Copy and paste the following code in Program.cs file in the Host project.
using System.ServiceModel;
using System;
namespace Host
{
class Program
{
public static void Main()
{
using (ServiceHost host = new ServiceHost
(typeof(ReportService.ReportService)))
{
host.Open();
Console.WriteLine("Host started @ " + DateTime.Now.ToString());
Console.ReadLine();
}
}
}
}Step 10: Set Host project as the startup project and run the application by pressing CTRL + F5 key. At this point we have the WCF service up and running.
Step 11: Now let's create a client for the WCF service. Create a new windows forms application with name = DuplexClient
Step 12: Add a service reference to ReportService. Right click on References folder and select Add Service Reference. In the Add Service Reference window type Address = http://localhost:8080/ and click GO button. This should bring up the ReportService. In the Namespace textbox type ReportService and click OK. Also add a reference to System.ServiceModel assembly.
Step 13: Design Form1 as shown below, with a button and a textbox controls. Set the following properties on button1
Name = btnProcessReport
Text = Process Report
Step 14: Double click on the button to generate the "click event handler" method. Copy and paste the following code in Form1.cs file.
using System;
using System.ServiceModel;
using System.Windows.Forms;
namespace DuplexClient
{
// The Form1 class implements IReportServiceCallback interface
public partial classForm1 : Form, ReportService.IReportServiceCallback
{
public Form1()
{
InitializeComponent();
}
private void btnProcessReport_Click(object sender, EventArgse)
{
InstanceContext instanceContext = new InstanceContext(this);
ReportService.ReportServiceClientclient =
new ReportService.ReportServiceClient(instanceContext);
client.ProcessReport();
}
// This method recevies the progress update from the WCF service
// Report processing percentage is displayed in the textbox control
public void Progress(int percentageComplete)
{
textBox1.Text = percentageComplete.ToString() + " % completed";
}
}
}Step 15: Run client the application by pressing CTRL + F5 and click on "Process Report" button. At this point we will get the following exception.
This operation would deadlock because the reply cannot be received until the current Message completes processing. If you want to allow out-of-order message processing, specify ConcurrencyMode of Reentrant or Multiple on ServiceBehaviorAttribute.
Step 16: To fix the above error, we need to do 2 things
a) In ReportService.cs file, set ConcurrencyMode to Reentrant as shown below.
[ServiceBehavior(ConcurrencyMode=ConcurrencyMode.Reentrant)]
public class ReportService : IReportService
b) In Form1.cs file in DuplexClient project, set UseSynchronizationContext to false as shown below.
[CallbackBehavior(UseSynchronizationContext = false)]
public partial class Form1 : Form, ReportService.IReportServiceCallback
At this point run the service. Update the service reference in the DuplexClient project. Finally run the client project and click Process Report button. So, we have just seen how to implement Duplex messaging pattern using Request/Reply operations.
Now, let's discuss implementing Duplex messaging pattern using OneWay operations.
Step 1: Remove ServiceBehavior attribute that sets ConcurrencyMode to Reentrant from ReportService.cs file
public class ReportService : IReportService
Step 2: Remove CallbackBehavior attribute that sets UseSynchronizationContext to false from Form1.cs file in DuplexClient project.
public partial class Form1 : Form, ReportService.IReportServiceCallback
Step 3: Set ProcessReport() and Progress() operation contracts to OneWay in IReportService.cs file in ReportService project
[ServiceContract(CallbackContract = typeof(IReportServiceCallback))]
public interface IReportService
{
[OperationContract(IsOneWay = true)]
void ProcessReport();
}
public interface IReportServiceCallback
{
[OperationContract(IsOneWay = true)]
void Progress(int percentageComplete);
}At the point run the service. Update the service reference in the DuplexClient project. Finally run the client project and click Process Report button. With these changes we are now using Duplex messaging pattern using OneWay operations.