微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

稳扎稳打Silverlight(23) - 2.0通信之调用WCF的双向通信(Duplex Service)

[索引页]
[源码下载]


稳扎稳打Silverlight(23) - 2.0通信之调用WCF的双向通信(Duplex Service)


作者:webabcd


介绍
Silverlight 2.0 调用 WCF 的双向通信服务(Duplex Service) 。开发一个服务端主动向客服端发送股票信息的程序,首先客户端先向服务端发送需要监控的股票的股票代码,然后服务端在该股信息发生变化的时候将信息推送到客户端。
    服务端:
        定义服务契约及回调接口
        从当前上下文获取回调的客户端信道
        需要的话则向客户端信道“推”消息
    客户端:
        构造 PollingDuplexHttpBinding 并在其上创建 IDuplexSessionChannel 的信道工厂
        异步方式打开信道工厂
        异步方式打开信道
        构造需要发送到服务端的消息 System.ServiceModel.Channels.Message
        异步向服务端发送消息
        监听指定信道,用于异步方式接收服务端返回的消息
        不需要再接收服务端的消息则关闭信道


在线DEMO
http://www.voidcn.com/article/p-ounmxjds-tq.html

示例 
服务端:
IDuplexService.cs

using System;

using System.Collections.Generic;

using System.Linq;

using System.Runtime.Serialization;

using System.ServiceModel;

using System.Text;


using System.ServiceModel.Channels;


/// <summary>
/// IDuplexService - 双工(Duplex)服务契约
/// CallbackContract - 双工(Duplex)服务的回调类型
/// </summary>

[ServiceContract(Namespace = "Silverlight20",CallbackContract = typeof(IDuplexClient))]

public interface IDuplexService

{

         /// <summary>

         /// 客户端向服务端发送消息的方法

         /// </summary>

         /// <param name="receivedMessage">客户端向服务端发送的消息 System.ServiceModel.Channels.Message</param>

        [OperationContract(IsOneWay = true)]

         void SendStockCode(Message receivedMessage);

}


/// <summary>
/// 双工(Duplex)服务的回调接口
/// </summary>

public interface IDuplexClient

{

         /// <summary>

         /// 客户端接收服务端发送过来的消息的方法

         /// </summary>

         /// <param name="returnMessage">服务端向客户端发送的消息 System.ServiceModel.Channels.Message</param>

        [OperationContract(IsOneWay = true)]

         void ReceiveStockMessage(Message returnMessage);

}
 
DuplexService.cs

using System;

using System.Collections.Generic;

using System.Linq;

using System.Runtime.Serialization;

using System.ServiceModel;

using System.Text;


using System.ServiceModel.Channels;

using System.Threading;

using System.ServiceModel.Activation;

using System.IO;


/// <summary>
/// Duplex 服务的服务端的实现
/// 本文以客户端向服务端提交股票代码,服务端定时向客户端发送股票信息为例
/// </summary>

public class DuplexService : IDuplexService

{

        IDuplexClient _client;

         bool _status = true;


         /// <summary>

         /// 客户端向服务端发送股票代码方法

         /// </summary>

         /// <param name="receivedMessage">包含股票代码的 System.ServiceModel.Channels.Message </param>

         public void SendStockCode(Message receivedMessage)

        {

                 // 获取当前上下文的回调信道

                _client = OperationContext.Current.GetCallbackChannel<IDuplexClient>();


                 // 如果发生错误则不再执行

                OperationContext.Current.Channel.Faulted += new EventHandler( delegate { _status = false; });


                 // 获取用户提交的股票代码

                 string stockCode = receivedMessage.GetBody< string>();


                 // 每3秒向客户端发送一次股票信息

                 while (_status)

                {

                         // 构造需要发送到客户端的 System.ServiceModel.Channels.Message

                         // Duplex 服务仅支持 Soap11 , Action 为请求的目的地(需要执行的某行为的路径)

                        Message stockMessage = Message.CreateMessage(

                                MessageVersion.soap11,

                                 "Silverlight20/IDuplexService/ReceiveStockMessage",

                                 string.Format( "StockCode: {0}; StockPrice: {1}; CurrentTime: {2}",

                                        stockCode,

                                         new Random().Next(1,200),

                                        DateTime.Now.ToString()));


                         try

                        {

                                 // 向客户端“推”数据

                                _client.ReceiveStockMessage(stockMessage);

                        }

                         catch (Exception ex)

                        {

                                 // 出错则记日志

                                 using (StreamWriter sw = new StreamWriter( @"C:\Silverlight_Duplex_Log.txt",true))

                                {

                                        sw.Write(ex.ToString());

                                        sw.WriteLine();

                                }

                        }


                        System.Threading.Thread.Sleep(3000);

                }

        }

}
 
PollingDuplexServiceHostFactory.cs

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;


using System.ServiceModel;

using System.ServiceModel.Channels;

using System.ServiceModel.Activation;


/* 以下部分摘自文档 */


// 服务 svc 文件的 Factory 要指定为此类

public class PollingDuplexServiceHostFactory : ServiceHostFactoryBase

{

         public override ServiceHostBase CreateServiceHost( string constructorString,

                Uri[] baseAddresses)

        {

                 return new PollingDuplexSimplexServiceHost(baseAddresses);

        }

}


class PollingDuplexSimplexServiceHost : ServiceHost

{

         public PollingDuplexSimplexServiceHost( params System.Uri[] addresses)

        {

                 base.InitializeDescription( typeof(DuplexService),new UriSchemeKeyedCollection(addresses));

        }


         protected override void InitializeRuntime()

        {

                 // 配置 WCF 服务与 Silverlight 客户端之间的 Duplex 通信

                 // Silverlight 客户端定期轮询网络层上的服务,并检查回调信道上由服务端发送的所有新的消息

                 // 该服务会将回调信道上的由服务端发送的所有消息进行排队,并在客户端轮询服务时将这些消息传递到该客户端


                PollingDuplexBindingElement pdbe = new PollingDuplexBindingElement()

                {

                         // ServerPollTimeout - 轮询超时时间

                         // InactivityTimeout - 服务端与客户端在此超时时间内无任何消息交换的情况下,服务会关闭其会话


                        ServerPollTimeout = TimeSpan.FromSeconds(3),

                        InactivityTimeout = TimeSpan.FromMinutes(1)

                };


                 // 为服务契约(service contract)添加一个终结点(endpoint)

                 // Duplex 服务仅支持 Soap11

                 this.AddServiceEndpoint(

                         typeof(IDuplexService),

                         new CustomBinding(

                                pdbe,

                                 new TextMessageEncodingBindingElement(

                                        MessageVersion.soap11,

                                        System.Text.Encoding.UTF8),

                                 new HttpTransportBindingElement()),

                                "");


                 base.InitializeRuntime();

        }

}
 
DuplexService.svc
<%@ ServiceHost Language="C#" Debug="true" Service="DuplexService" CodeBehind="~/App_Code/DuplexService.cs" Factory="PollingDuplexServiceHostFactory" %>
 
 

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐