昨天,我写了一篇很长的文章来讲述在工作流服务中如何实现双工通信。其中最重要的是工作流服务不支持定义在ServiceContract上的回调通道这种WCF风格的双工通信,而是通过叫做持久化双工(durable duplex)的方式实现的,回调契约是独立的,并且客户端不得不创建一个ServiceHost做为一个完全的WCF服务。回调地址在客户端通过使用CallbackContextMessageProperty传递,在服务端使用回调关联句柄来连接Receive活动和发送回调的Send活动。
使用 CallbackContextMessageProperty 和 CorrelationHandle 的问题是什么?
除了在客户端和服务端需要做更多的配置外,本质上没有什么真正的问题。因为标准的WCF回调在使用ServiceHost处理客户端回调的工作流服务中是不支持的。这是非常不幸的,因为这会导致很多问题,特别是在使用Silverlight作为客户端的时候。然而所有的CallbackContextMessageProperty和CorrelationHandle的复杂性仅仅是传递一个简单的字符串即回调地址。而且Send活动有能力使用EndpointAddress属性来动态指定回调地址。
将回调的地址作为参数传递到我们最初的服务调用在这种情况下不能再简单些吗?
恰好可以,剩下部分我会展示如何做到这一点。
我们从前一篇文章的DuplexDemo解决方案开始,你可以在这里下载代码。
首先是增加一个字符串变量“callbackAddress”,更新Receive活动接收这个字符串为第二个参数。
我们需要设置Send活动的EndpointAddress属性来传递地址“New Uri(callbackAddress)” ,如下图:
现在我们可以从变量,Receive活动的CorrelationInitializers和Send活动的CorrelatesWith中移除掉callbackHandle,然后我需要在客户端的代码中去掉OperationContextScope,CallbackContextMessageProperty并且添加回调地址作为GetData()的第二个参数,代码如下:
就是这么简单!~
除了更简单之外还有另一个好处,由于回调地址作(代替隐藏的上下文头数据块)为一个一般的数据来传递,我们可以检查它是否被传递,如果没有我们就跳过回调处理部分。这使得工作流服务对于客户端来说仍然是可用的。我很喜欢这种简单的方式来实现,但这并不意味着持久化双工永远不该使用,他自然有他适用的场景,这种简单方式在需要的时候是最合适的。
代码下载: SimpleDuplexDemo.zip