- Windows Communication Foundation(WCF)是由微软发展的一组数据通信的应用程序开发接口
- WCF双工:客户端请求服务端,服务端处理完后再主动调用客户端;
服务端步骤
- 服务端:新增2个接口(1个服务契约接口、1个回调接口),1个服务契约接口派生实现类、配置文件新增配置、启动服务监听端口,
[ServiceContract(CallbackContract = typeof(ICallback))]
public interface ICalculateService
{
[OperationContract(IsOneWay = true)]
void Add(int x, int y);
}
public interface ICallback
{
[OperationContract(IsOneWay =true)]
void Show(int n);
}
public class CalculateService : ICalculateService
{
public void Add(int x, int y)
{
int result = x + y;
Thread.Sleep(2000);
ICallback callback = OperationContext.Current.GetCallbackChannel<ICallback>();
callback.Show(result);
}
}
- 服务端:WCF配置文件,在web.config/app.config里
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="CalculateServicebehavior">
<serviceDebug httpHelpPageEnabled="false"/>
<serviceMetadata httpGetEnabled="false"/>
<serviceTimeouts transactionTimeout="00:10:00"/>
<serviceThrottling maxConcurrentCalls="1000" maxConcurrentInstances="1000" maxConcurrentSessions="1000"/>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<netTcpBinding>
<binding name="tcpbinding">
<security mode="None">
<transport clientCredentialType="None" protectionLevel="None"/>
</security>
</binding>
</netTcpBinding>
</bindings>
<services>
<service name="MySOA.Service.CalculateService" behaviorConfiguration="CalculateServicebehavior">
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:11111/CalculatorService"/>
</baseAddresses>
</host>
<endpoint address="" binding="netTcpBinding" bindingConfiguration="tcpbinding" contract="MySOA.Interface.ICalculateService"/>
<endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange"/>
</service>
</services>
</system.serviceModel>
- 启动WCF服务,比如用控制台程序
static void InitService()
{
List<ServiceHost> serviceHosts = new List<ServiceHost>()
{
new ServiceHost(typeof(CalculateService))
};
foreach (var serviceHost in serviceHosts)
{
serviceHost.Opened += (s, e) => { Console.WriteLine(serviceHost.GetType().Name + "启动了..."); };
serviceHost.Open();
}
Console.WriteLine("输入任何字符,中止服务");
Console.ReadKey();
foreach (var serviceHost in serviceHosts)
{
serviceHost.Close();
}
}
客户端步骤
- 引用——添加服务引用,输入服务端配置文件里的地址;
- 创建一个类,继承服务引用里的Callback接口(
MySOAClient.ICalculateServiceCallback
),并实现方法,此方法届时为服务端主动调用的;
public class MyCallback : MySOAClient.ICalculateServiceCallback
{
public void Show(int n)
{
Console.WriteLine($"n:{n}");
}
}
- 在主函数里创建
MyCallback
实例并作为参数传入CalculateServiceClient
对象,最后调用服务端的方法Add
;
static void Main(string[] args)
{
MySOAClient.CalculateServiceClient client = null;
try
{
InstanceContext context = new InstanceContext(new MyCallback());
client = new MySOAClient.CalculateServiceClient(context);
client.Add(3, 9);
client.Close();
}
catch (Exception ex)
{
if (client != null)
client.Abort();
Console.WriteLine(ex.Message);
}
Console.Read();
}
- 客户端启动后,调用
Add
方法,服务端收到并执行Add
方法,再执行Callback,再实现对对客户端的回调;