双工通信在很多时候都很有用,比如一个服务允许通知用户当前的进度情况。一般情况下,我们可以使用WCF来实现,你可以通过使用指定CallbackContract的ServiceContract属性的服务使用双工,如服务器端的代码如下:
但是这种方式并不适用于WF4中,因为WF4中没有ServiceContract属性,不能指定CallbackContract。然而WF4支持双工通信。
代替正常WCF的双工服务,工作流服务使用一种架构被称作持久化双工,这是一种更分离的方式来实现双工通信,他的优点是通信的两端都是独立工作的,这也意味着一般的双工通信的缺点在这里不复存在。我们甚至可以在回调端使用一个完全不同于原始请求的绑定。不过作为客户端有一个缺点就是必须创建自己的ServiceHost并且做为一个完整的WCF服务,比正常的双工通信要复杂一些。下面我们看下如何实现。
第一步创建工作流服务,这个和其他的WCF工作流服务应用程序是一样的,持久化的双工需要一个上下文绑定,所以我们首先将绑定更改为wsHttpContextBinding如下:
下一步添加一个客户端的控制台应用程序用来调用工作流服务,添加服务引用及如下代码:
然后我们添加双工部分,首先我们要在客户端添加一个ServiceHost暴漏一个回调契约和回调服务定义,不像正常的双工服务定义契约在服务端,我们需要在客户端定义契约,代码如下:
下一步宿主这个服务,代码如下:
下一步是使工作流服务调用返回给客户端。 为此,我们需要做一些的事情。 首先,我们要让工作流服务知道在哪里可以回调。 这是通过将一个 CallbackContextMessageProperty 回调地址添加到请求标头。
这可以通过使用一个 OperationContextScope 来替换proxy.GetDate() 实现,代码如下:
然后我们更新工作流本身,首先我们先增加一个CorrelationHandle变量表示回调关联。如下图:
下一步在GetData Receive活动的CorrelationInitializer中初始化callbackHandle,如下图:
下一步我们需要一个Send活动来发送响应给客户端,设置其CorrelatesWith为之前初始化的callbackHandle,如下图:
最后我们设置Send活动属性来匹配客户端的回调服务,如下:
注意上面的设置中我们没有设置AddressUri和EndpointAddress,因为他可以通过请求上下文和回调关联句柄来提供,我们还设置了basicHttpBinding绑定,因为这个是客户端使用的。
最后我们需要增加一个传递回来的消息,如下:
都完成之后,我们可以运行服务端和客户端,可以得到服务端的回调在客户端上:
如果忘记设置回调CorrelationHandle会导致客户端得不到消息,会得到一个异常“Endpoint with Name='<not specified>' and ServiceContract '<not specified>' has a null or empty Uri property. A Uri for this Endpoint must be provided.”,这是由于Send活动找不到他的回调地址导致。
不能从客户端传递空的上下文,CallbackContextMessageProperty有几个构造函数重载,一个只有一个EndpointAddress参数,没有上下文参数。看起来好像是一个很好的选择我们可以不用指定任何的上下文信息。不幸的是当Send活动尝试寻找他的回调地址的时候会导致ArgumentNullException异常,异常信息为:"Value cannot be null. Parameter name: context".
代码下载:DuplexDemo.zip
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器