现在的位置: 首页 > 综合 > 正文

[Silverlight学习笔记]创建Silverlight 3与WCF之间的 双工通信

2012年08月24日 ⁄ 综合 ⁄ 共 3351字 ⁄ 字号 评论关闭

本文简述的是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);
        }
 

示例源码下载 

 

抱歉!评论已关闭.