我所知道的CallbackContract in WCF


由於WCF中提供了CallbackContract屬性,所以在雙工通信中,我們可以很方便的和Server進行通信。雖然查遍了MSDN,也看過了它提供的例子,但是還是不知道怎么來使用(因為MSDN中只是給你提供了Server端的調用方法,並沒有客戶端的調用方式,所以例子沒法兒跑起來,當然也就不能夠從示例中看出CallbackContract屬性的工作方式,鄙視下,呵呵)。在這篇文章中,我要做的就是讓這個例子能夠順利地跑起來,從而了解CallbackContract的工作方式。

服務端編寫

首先,創建一個名稱為CallbackContractWCF的控制台項目,添加一個DuplexHello類作為我們的Service,具體代碼就Copy了MSDN上面的:

View Code
using System;
using System.ServiceModel;
using System.Threading;

namespace CallbackContractWCF
{
    [ServiceContract(Name = "SampleDuplexHello", CallbackContract = typeof(IHelloCallbackContract), SessionMode = SessionMode.Required)]
    public interface IDuplexHello
    {
        [OperationContract(IsOneWay = true)]
        void Hello(string greeting);
    }

    public interface IHelloCallbackContract
    {
        [OperationContract(IsOneWay = true)]
        void Reply(string responseToGreeting);
    }

    public class DuplexHello:IDuplexHello
    {
        public DuplexHello()
        {
            Console.WriteLine("Service object created: " + this.GetHashCode().ToString());
        }

        ~DuplexHello()
        {
            Console.WriteLine("Service object distroyed: " + this.GetHashCode().ToString());
        }

        public void Hello(string greeting)
        {
            Console.WriteLine("Caller sent: "+greeting);
            Console.WriteLine("Session ID: "+OperationContext.Current.SessionId);
            Console.WriteLine("Waiting two seconds before returning call.");
            Thread.Sleep(2000);
            IHelloCallbackContract callerProxy = OperationContext.Current.GetCallbackChannel<IHelloCallbackContract>();
            string response = "Service object " + this.GetHashCode().ToString() + " received." + greeting;
            Console.WriteLine("Sending back: " + response);
            callerProxy.Reply(response);
        }
    }
}

從這個類中,我們可以看到它有一個IHelloCallbackContract的接口,由於它在ServiceContract中被標記為CallbackContract = typeof(IHelloCallbackContract),所以它用於客戶端回調。意即,服務端可以通過此接口中的方法將數據發送給客戶端,客戶端只需要實現此接口,即可接收到服務端發送過來的消息。

然后是創建配置文件,請參見我的文章:基於net.tcp的WCF配置實例解析。這里我們使用的EndPoint為:net.tcp://127.0.0.1/DuplexHello,創建好App.config配置文件后,拷貝到CallbackContractWCF項目下,然后打開Program.cs文件,編碼以便讓服務端能夠啟動監聽:

View Code
using (ServiceHost host = new ServiceHost(typeof(DuplexHello)))
            {
                ServiceMetadataBehavior smb = host.Description.Behaviors.Find<ServiceMetadataBehavior>();
                if (smb == null)
                {
                    host.Description.Behaviors.Add(new ServiceMetadataBehavior());
                }
//暴露MetaData,以便能夠讓SvcUtil.exe工具生成客戶端代理類和配置文件
                host.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexTcpBinding(), "mex");
                host.Open();
                Console.WriteLine("service listen on endpoint ...");
                Console.WriteLine("Press ENTER to stop ...");
                Console.ReadLine();
                host.Abort();
                host.Close();
            }

好了,啟動服務端,我們可以看到如下界面,服務端啟動成功了:

客戶端編寫 

下面開始來編寫客戶端。

首先打開SvcUtil.exe,按照文章:基於net.tcp的WCF配置實例解析 中介紹的方法,生成output.config文件和DuplexHello.cs代理類文件。

其次創建一個名稱為CallbackContractWCFClient的Windows Form Application項目,將上面的兩個文件拷貝進來,並修改output.config名稱為App.config。

然后打開ClientForm窗體,繼承自SampleDuplexHelloCallback接口(這個接口也就是服務端的IHelloCallbackContract接口的代理),然后編寫以下代碼進行數據發送和接收:

View Code
using System;
using System.Windows.Forms;
using System.ServiceModel;

namespace CallbackContractWCFClient
{
    public partial class ClientForm : Form, SampleDuplexHelloCallback
    {
        public ClientForm()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            InstanceContext site = new InstanceContext(this);
            SampleDuplexHelloClient client = new SampleDuplexHelloClient(site);

            string msg =" This is a Client Message sent to Server side...";
            label1.Text = "Client Sent: " + msg;
            client.Hello(msg);
           
        }

        public void Reply(string responseToGreeting)
        {
            label2.Text = "Server Reply: " + responseToGreeting;
        }

    }
}

這樣,我們的服務端和客戶端就寫好了,接下來運行,結果顯示如下:

服務端:

 客戶端:

源碼下載

點擊這里下載


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM