本文简述的是silverlight3中使用wcf的pulling duplex的一个比效简单双工应用,一个简易的聊天室(不完善,只是一个Demo);
1.Wcf 服务将会使用 Silverlight 3 SDK 附带的 PollingDuplex。
要添加对 System.ServiceModel.PollingDuplex 程序集的引用,
注意的,Silverlight 3 SDK中有两个System.ServiceModel.PollingDuplex.dll文件,
一个是客户端也就是Silverlight程序集里引用,
路径是C:\Program Files\Microsoft SDKs\Silverlight\v3.0\Libraries\Client\System.ServiceModel.PollingDuplex.dll
而WCF服务引用的dll的路径是C:\Program Files\Microsoft SDKs\Silverlight\v3.0\Libraries\Server\System.ServiceModel.PollingDuplex.dll
2.定义回调服务契约
回调契约是用于 WCF 服务向 Silverlight 客户端推送数据的接口:
[ServiceContract] public interface IServiceCallback { [OperationContract(IsOneWay = true)] void GetData(string data); }
3.定义服务契约
用标识为 ServiceContract 属性的WCF服务,并将 CallbackContract 设置为有效的类型:
[ServiceContract(Namespace="",CallbackContract=typeof(IServiceCallback))] public interface IService { [OperationContract(IsOneWay = true)] void SentData(string data); [OperationContract(IsOneWay = true)] void InitData(); }
4.将数据推送到客户端之调用回调合同方法。
要将数据发送到客户端,我们首先必须获得一个有效的回调通道和调用的方法之一。
在本例中我们通过调用 OperationContext.Current.GetCallbackChannel <iduplexservicecallback>获取回调通道)
并调用它的 GetData() 方法把数据推送至所有在线的客户端:
public class Service : IService { static List<IServiceCallback> cilents = new List<IServiceCallback>(); public void SentData(string data) { IServiceCallback iscCurrent = OperationContext.Current.GetCallbackChannel<IServiceCallback>(); int num = cilents.IndexOf(iscCurrent); foreach (IServiceCallback isc in cilents) { try { isc.GetData((num + 1) + "说:" + data); } catch { } } }}
5.创建Service Host Factory。
手动去创建 Service Host Factory 提供服务终结点配置:
public class PollingDuplexServiceHostFactory:ServiceHostFactoryBase { public override ServiceHostBase CreateServiceHost(string constructorString, Uri[] baseAddresses) { //throw new NotImplementedException(); return new PollingDuplexSimplexServiceHost(baseAddresses); } } class PollingDuplexSimplexServiceHost : ServiceHost { public PollingDuplexSimplexServiceHost(params Uri[] addresses) { base.InitializeDescription(typeof(Service),new UriSchemeKeyedCollection(addresses)); base.Description.Behaviors.Add(new ServiceMetadataBehavior()); } protected override void InitializeRuntime() { //给服务添加一个终结点 this.AddServiceEndpoint(typeof(IService), new CustomBinding( new PollingDuplexBindingElement(), new BinaryMessageEncodingBindingElement(), new HttpTransportBindingElement() ),""); //添加元数据终结点 this.AddServiceEndpoint(typeof(IMetadataExchange),MetadataExchangeBindings.CreateMexHttpBinding(),"mex"); base.InitializeRuntime(); } }
然后将此Factory添加到服务中:
<%@ ServiceHost Language="C#" Debug="true" Service="SevendaysDuplex.Web.Service" CodeBehind="Service.svc.cs"
Factory="SevendaysDuplex.Web.PollingDuplexServiceHostFactory" %>
请注意有运行此服务之前请先把web.config文件中所有wcf相关的配置都删除。
6.在Silverlight 项目添加服务引用 。
注意我们要添加双工服务的引用时 ServiceReferences.ClientConfig 不会产生内容,因此我们必须手动将端点和地址的配置传递给服务客户端:
ServiceClient _sc; public ServiceClient SC { get { if (_sc == null) { EndpointAddress address = new EndpointAddress(GetAbsoluteUri("Service.svc")); CustomBinding binding = new CustomBinding( new PollingDuplexBindingElement(), new BinaryMessageEncodingBindingElement(), new HttpTransportBindingElement()); _sc = new ServiceClient(binding, address); _sc.GetDataReceived += new EventHandler<GetDataReceivedEventArgs>(_sc_GetDataReceived); } return _sc; } }
7.使用服务
使用双工的服务非常简单。与消费其他WCF服务没什么区别,我们只要处理 GetDataReceived 事件 (因为我们的回调契约公开的是 GetData 方法),并让 WCF 处理客户端/服务器通信。
void _sc_GetDataReceived(object sender, GetDataReceivedEventArgs e) { //throw new NotImplementedException(); LBMessage.Items.Add(e.data); }
示例源码下载