Search content within the blog

Wednesday, August 4, 2010

WsDualHttpBinding in WCF

Below is the complete code both the server and the client.

Server code
using System;
using System.ServiceModel;

namespace Microsoft.ServiceModel.Samples
{
// Define a duplex service contract.
// A duplex contract consists of two interfaces.
// The primary interface is used to send messages from client to service.
// The callback interface is used to send messages from service back to client.
// ICalculatorDuplex allows one to perform multiple operations on a running result.
// The result is sent back after each operation on the ICalculatorCallback interface.
[ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples", SessionMode=SessionMode.Required,
CallbackContract=typeof(ICalculatorDuplexCallback))]
public interface ICalculatorDuplex
{
[OperationContract(IsOneWay=true)]
void Clear();
[OperationContract(IsOneWay = true)]
void AddTo(double n);
[OperationContract(IsOneWay = true)]
void SubtractFrom(double n);
[OperationContract(IsOneWay = true)]
void MultiplyBy(double n);
[OperationContract(IsOneWay = true)]
void DivideBy(double n);
}

// The callback interface is used to send messages from service back to client.
// The Result operation will return the current result after each operation.
// The Equation opertion will return the complete equation after Clear() is called.
public interface ICalculatorDuplexCallback
{
[OperationContract(IsOneWay = true)]
void Result(double result);
[OperationContract(IsOneWay = true)]
void Equation(string eqn);
}

// Service class which implements a duplex service contract.
// Use an InstanceContextMode of PerSession to store the result
// An instance of the service will be bound to each duplex session
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
public class CalculatorService : ICalculatorDuplex
{
double result;
string equation;
ICalculatorDuplexCallback callback = null;

public CalculatorService()
{
result = 0.0D;
equation = result.ToString();
callback = OperationContext.Current.GetCallbackChannel();
}

public void Clear()
{
callback.Equation(equation + " = " + result.ToString());
result = 0.0D;
equation = result.ToString();
}

public void AddTo(double n)
{
result += n;
equation += " + " + n.ToString();
callback.Result(result);
}

public void SubtractFrom(double n)
{
result -= n;
equation += " - " + n.ToString();
callback.Result(result);
}

public void MultiplyBy(double n)
{
result *= n;
equation += " * " + n.ToString();
callback.Result(result);
}

public void DivideBy(double n)
{
result /= n;
equation += " / " + n.ToString();
callback.Result(result);
}

}

}
Server code - web.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<services>
<service
name="Microsoft.ServiceModel.Samples.CalculatorService"
behaviorConfiguration="CalculatorServiceBehavior">
<!-- this endpoint is exposed at the base address provided by host: http://localhost/servicemodelsamples/service.svc -->
<endpoint address=""
binding="wsDualHttpBinding"
contract="Microsoft.ServiceModel.Samples.ICalculatorDuplex" />
<!-- the mex endpoint is exposed at http://localhost/servicemodelsamples/service.svc/mex -->
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
</service>
</services>

<!--For debugging purposes set the includeExceptionDetailInFaults attribute to true-->
<behaviors>
<serviceBehaviors>
<behavior name="CalculatorServiceBehavior">
<serviceMetadata httpGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="False" />
</behavior>
</serviceBehaviors>
</behaviors>

</system.serviceModel>

</configuration>

Client code
using System;
using System.ServiceModel;

namespace Microsoft.ServiceModel.Samples
{
// The service contract is defined in generatedClient.cs, generated from the service by the svcutil tool.

// Define class which implements callback interface of duplex contract
public class CallbackHandler : ICalculatorDuplexCallback
{
public void Result(double result)
{
Console.WriteLine("Result({0})", result);
}

public void Equation(string eqn)
{
Console.WriteLine("Equation({0})", eqn);
}

}

class Client
{
static void Main()
{
// Construct InstanceContext to handle messages on callback interface
InstanceContext instanceContext = new InstanceContext(new CallbackHandler());

// Create a client with given client endpoint configuration
CalculatorDuplexClient client = new CalculatorDuplexClient(instanceContext);

Console.WriteLine("Press to terminate client once the output is displayed.");
Console.WriteLine();

// Call the AddTo service operation.
double value = 100.00D;
client.AddTo(value);

// Call the SubtractFrom service operation.
value = 50.00D;
client.SubtractFrom(value);

// Call the MultiplyBy service operation.
value = 17.65D;
client.MultiplyBy(value);

// Call the DivideBy service operation.
value = 2.00D;
client.DivideBy(value);

// Complete equation
client.Clear();

Console.ReadLine();

//Closing the client gracefully closes the connection and cleans up resources
client.Close();
}

}
}

Client code (app.config)

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>

<client>
<endpoint address="http://localhost/servicemodelsamples/service.svc"
binding="wsDualHttpBinding"
bindingConfiguration="Binding1"
contract="Microsoft.ServiceModel.Samples.ICalculatorDuplex" />
</client>

<bindings>
<!-- configure a WSDualHttpBinding that supports duplex communication -->
<wsDualHttpBinding>
<binding name="Binding1"
clientBaseAddress="http://localhost:8000/myClient/"
useDefaultWebProxy="true"
bypassProxyOnLocal="false">
</binding>
</wsDualHttpBinding>
</bindings>

</system.serviceModel>

</configuration>

3 comments:

  1. Having read this material, I have learned for myself a lot of the new. Thanks

    ReplyDelete
  2. if you host your WCF Server on Internet, does client which is sending response back required public IP

    ReplyDelete