双工通讯是指通讯双方可以同时互发消息
主要方法
OperationContext context=OperationContext.Current; //获取当前服务方法上下文
callback=context.GetCallbackChannel<ICallback>(); //获取回调契约(接口)实例对象,该对象由客户端通过通道传递过来
InstanceContext instance=new InstanceContext(new ImpCallback()) //创建一个InstanceContext实例对象,该对象传入一个实现了回调契约(接口)的实例
DuplexClient client=new DuplexClient(instance);//实例化客户端对象,传入回调契约实现,该方法由多个重载方法,如果配置中定义多个协议,需要指定是用哪个协议
如: client = new StudentDuplexClient(context, "NetTcpBinding_IStudentDuplex");
下面以简单示例演示:
-
服务端
using System.ServiceModel;
namespace WpfApp14.Services
{
[ServiceContract(Namespace ="WcfExamples",
SessionMode =SessionMode.Required, //回话模式为请求模式
CallbackContract =typeof(IStudentDuplexCallback))] //回调契约
public interface IStudentDuplex
{
[OperationContract(IsOneWay = true)]
void Login(string greeting);
}
}
using System.ServiceModel;
namespace WpfApp14.Services
{
public interface IStudentDuplexCallback
{
[OperationContract(IsOneWay = true)]
void Receive(string response);
}
}
using System.ServiceModel;
using WpfApp14.Models;
namespace WpfApp14.Services
{
public class StudentsDuplex : Student, IStudentDuplex
{
private IStudentDuplexCallback callback;
public StudentsDuplex()
{
OperationContext context = OperationContext.Current;
callback = context.GetCallbackChannel<IStudentDuplexCallback>(); //获取客户端回调对象
}
public void Login(string greeting)
{
callback.Receive("Hello"+greeting); //通过回调接口对象(由客户端实现)回调客户端方法
System.Threading.Thread.Sleep(1000);
callback.Receive("你好,我是服务端");
}
}
}
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
ServiceHost host = new ServiceHost(typeof(StudentsDuplex));
try
{
host.Open();
foreach (var v in host.Description.Endpoints) {
txt.Text += v.ListenUri + "\n";
}
this.Title = this.Title+" WCF服务开始监听";
}
catch (Exception ex)
{
txt.Text = ex.Message;
}
}
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
<system.serviceModel>
<bindings>
<wsDualHttpBinding>
<binding name="WSDualHttpBinding_IStudentDuplex" />
</wsDualHttpBinding>
</bindings>
<services>
<service name="WpfApp14.Services.StudentsDuplex">
<endpoint address="" binding="wsDualHttpBinding" contract="WpfApp14.Services.IStudentDuplex" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:10020/StudentsDuplex"/>
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
using System;
using System.ServiceModel;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using WpfApp14.ServiceReference3; //引用服务端命名空间
namespace WpfApp14.Examples
{
/// <summary>
/// Page3.xaml 的交互逻辑
/// </summary>
public partial class Page3 : Page,IStudentDuplexCallback
{
private StudentDuplexClient client; // 定义客户端引用
public Page3()
{
InitializeComponent();
}
public void Receive(string response)
{
textBlock1.Text+="\n收到服务端发来的信息:"+response;
}
private async void Btn1_Click(object sender, RoutedEventArgs e)
{
InstanceContext context = new InstanceContext(this);
client = new StudentDuplexClient(context);
textBlock1.Text += "\n等待接收";
Task login = client.LoginAsync("张三");
while (login.IsCompleted == false) {
textBlock1.Text += ".";
await Task.Delay(TimeSpan.FromMilliseconds(500));
}
await login;
}
}
}
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
<system.serviceModel>
<client>
<endpoint address="http://localhost:10020/StudentsDuplex" binding="wsDualHttpBinding"
bindingConfiguration="WSDualHttpBinding_IStudentDuplex" contract="ServiceReference3.IStudentDuplex"
name="WSDualHttpBinding_IStudentDuplex">
<identity>
<userPrincipalName value="ZJZL-20240528TP\Administrator" />
</identity>
</endpoint>
<endpoint address="net.tcp://localhost:10021/StudentsDuplex"
binding="netTcpBinding" bindingConfiguration="NetTcpBinding_IStudentDuplex"
contract="ServiceReference3.IStudentDuplex" name="NetTcpBinding_IStudentDuplex">
<identity>
<userPrincipalName value="ZJZL-20240528TP\Administrator" />
</identity>
</endpoint>
</client>
<bindings>
<wsDualHttpBinding>
<binding name="WSDualHttpBinding_IStudentDuplex" />
</wsDualHttpBinding>
</bindings>
</system.serviceModel>
</configuration>