程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> 利用WCF的Duplex服務向Winform程序推送消息

利用WCF的Duplex服務向Winform程序推送消息

編輯:關於.NET

先看運行效果:在網頁中發送消息【如圖】,利用WCF的Duplex服務向Winform 程序推送消息,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的Duplex服務中取得要發送的消息推送到Winform端, SendMessage.aspx的代碼如下:

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 用來定義消息接收接口和回調接口

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秒鐘推送一次:

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<ISendMessageServiceCallB ack>();
            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 ,這樣才支持 WCF的Duplex服務

<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的Duplex服務已創建,拷貝該服務的地址,例如在我本機上 是:http://localhost:1407/SendMessageService.svc,並在WinApp項目中增加 該服務的引用

GetMessageForm.cs 實現如下:

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

    }

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved