(转)贾君鹏你妈妈喊你回家吃饭-利用WCF的Duplex推送消息

原文地址:http://www.cnblogs.com/xiaozhuang/archive/2009/07/22/1528712.html

 

 

有点标题党了,最近因工作需要,想利用WCF的Duplex服务向Winform程序推送消息,写了个示例,主要参考了artech的相关文章和其他一些利用WCF向SilverLight客户端推送消息的文章。
先看运行效果:在网页中发送消息【如图】,Winform端接收到消息


先建立两个项目,一个WebForm 项目和一个WinForm项目,并在项目下建立好各自需要的文件


SendMessage.aspx 是发送消息的Web页面
ISendMessageService.cs 和 SendMessageService.svc用来实现WCF的Duplex服务
GetMessageForm.cs 是接收消息的Winform窗口
当然,还需要建立一个消息实体文件:MessageEntity.cs,为简单起见,只给他定义一个属性。

[DataContract]
   
public class MessageEntity
    {
        [DataMember]
       
public string Content { get ; set ; }
    }

基本原理是消息发送的页面将要发送的消息列表保存在全局缓存中,在WCF服务中取得要发送的消息推送

到Winform端,SendMessage.aspx的代码如下:

ContractedBlock.gif ExpandedBlockStart.gif Code
protected void btnSend_Click(object sender, EventArgs e)
        {
            MessageEntity message
= new MessageEntity();
            message.Content
= txtMessageContent.Text;

            List
<MessageEntity> messageList = HttpRuntime.Cache["MessageEntityList"] as List<MessageEntity>;
           
if (messageList == null)
            {
                messageList
= new List<MessageEntity>();
                messageList.Add(message);
                HttpRuntime.Cache.Add(
"MessageEntityList", messageList, null, System.Web.Caching.Cache.NoAbsoluteExpiration, System.Web.Caching.Cache.NoSlidingExpiration, System.Web.Caching.CacheItemPriority.Default, null);
            }
           
else
            {
                messageList.Add(message);
                HttpRuntime.Cache[
"MessageEntityList"] = messageList;
            }

            lbCacheCount.Text
= messageList.Count.ToString();
        }

ISendMessageService.cs 用来定义消息接收接口和回调接口

ContractedBlock.gif ExpandedBlockStart.gif Code
[ServiceContract(CallbackContract = typeof(ISendMessageServiceCallBack))]
   
public interface ISendMessageService
    {
        [OperationContract(IsOneWay
= true)]
       
void GetMessage();
    }

   
public interface ISendMessageServiceCallBack
    {
        [OperationContract(IsOneWay
= true)]
       
void ReceiveMessage(MessageEntity messageEntity);
    }

SendMessageService.svc.cs 用来实现将缓存中的消息列表一个一个的推送出去,采用Timer类每2-5秒钟推送一次:

ContractedBlock.gif ExpandedBlockStart.gif Code
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]
   
public class SendMessageService : ISendMessageService
    {
        ISendMessageServiceCallBack callback;
        Timer heartTimer;
        Random random
= new Random();

       
#region ISendMessageService 成员

       
public void GetMessage()
        {
            callback
= OperationContext.Current.GetCallbackChannel<ISendMessageServiceCallBack>();
            heartTimer
= new Timer(new TimerCallback(heartTimer_Elapsed), null, 3000, Timeout.Infinite);
        }

       
#endregion

       
private void heartTimer_Elapsed(object data)
        {
            List
<MessageEntity> messageList = HttpRuntime.Cache["MessageEntityList"] as List<MessageEntity>;
           
if (messageList != null && messageList.Count > 0)
            {
                MessageEntity message
= messageList[0];
                messageList.Remove(message);
                HttpRuntime.Cache[
"MessageEntityList"] = messageList;
                callback.ReceiveMessage(message);
            }
           
int interval = random.Next(2000, 5000);
            heartTimer.Change(interval, Timeout.Infinite);
        }
    }

记得修改Web.Config中EndPoint Binding 为wsDualHttpBinding ,这样才支持Duplex服务

ContractedBlock.gif ExpandedBlockStart.gif Code
<service behaviorConfiguration="WebApp.SendMessageServiceBehavior" name="WebApp.SendMessageService">
               
<endpoint address="" binding="wsDualHttpBinding" contract="WebApp.ISendMessageService">
                   
<identity>
                       
<dns value="localhost"/>
                   
</identity>
               
</endpoint>
               
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
           
</service>

WebApp项目的工作已经完成,若没有错误可在浏览器中看到该WCF服务已创建,拷贝该服务的地址,例如在我本机上是:http://localhost:1407/SendMessageService.svc,并在WinApp项目中增加该服务的引用
GetMessageForm.cs 实现如下:

ContractedBlock.gif ExpandedBlockStart.gif Code
public partial class GetMessageForm : Form,ISendMessageServiceCallback
    {
        SendMessageServiceClient client;

       
public GetMessageForm()
        {
            InitializeComponent();
            client
= new SendMessageServiceClient(new System.ServiceModel.InstanceContext(this));
        }

       
private void btnStartGet_Click(object sender, EventArgs e)
        {
            client.GetMessage();
        }

       
private delegate void UpdateListBoxDelegate(string Message);
       
private void UpdateListBox(string message)
        {
           
this.listbMessage.Items.Add(message);
            listbMessage.SelectedIndex
= listbMessage.Items.Count - 1;
        }
       
#region ISendMessageServiceCallback 成员

       
public void ReceiveMessage(MessageEntity messageEntity)
        {
           
if (true == listbMessage.InvokeRequired)
            {
                listbMessage.Invoke(
new UpdateListBoxDelegate(UpdateListBox), messageEntity.Content);
            }
           
else
            {
                UpdateListBox(messageEntity.Content);
            }
        }

       
#endregion

    }

源代码打包下载

转载于:https://www.cnblogs.com/fcsh820/archive/2012/04/30/2476986.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值