在双向通信中至少要定义两个服务,一个服务是供消费程序消费的,另一个则是在callBack的时候调用的服务,这个服务应该由消费程序实现。
其次,就是在服务端实现这些契约(说白了就是实现上面定义的接口)。在开发中,我们经常会把这个实现独立出来,方便在不同的宿主中发布这些服务。
最后,实现客户端。在双向通信中,客户端也是服务端,因为它也实现了服务契约。
简单双向通讯程序编写 普通方式
服务端代码编写
Service 服务端
[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);
}
public interface ICalculatorDuplexCallback //回调接口
{
[OperationContract(IsOneWay = true)]
void Result(double result);
[OperationContract(IsOneWay = true)]
void Equation(string eqn);
}
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
public class CalculatorService : ICalculatorDuplex
{
double result = 0.0D;
string equation;
public CalculatorService()
{
equation = result.ToString();
}
public void Clear()
{
Callback.Equation(equation + " = " + result.ToString());
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);
}
ICalculatorDuplexCallback Callback
{
//获取当前客户端ICalculatorDuplexCallback实例的通道
get
{
return OperationContext.Current.GetCallbackChannel<ICalculatorDuplexCallback>();
}
}
}
Client: 客户端
// 其中实现双工合同的回调接口定义类
public class CallbackHandler : ICalculatorDuplexCallback
{
public void Result(double result)
{
Console.WriteLine("Result({0})", result);
}
public void Equation(string eqn)
{
Console.WriteLine("Equation({0})", eqn);
}
}
static void Main()
{
//构建实例上下文来处理回调接口上的消息
InstanceContext instanceContext = new InstanceContext(new CallbackHandler());
// 创建客户端实例
CalculatorDuplexClient client = new CalculatorDuplexClient(instanceContext);
Console.WriteLine("Press <ENTER> to terminate client once the output is displayed.");
Console.WriteLine();
// Call the AddTo service operation.
double value = 100.00D;
client.AddTo(value);
......
}
配置文件编写:
<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 athttp://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>