背景:使用WCF實現跨進程普通函數調用,帶回調的函數調用。
(轉載請注明來源:cnblogs coder-fang)
- 解決方案示例圖:
- 項目說明,WCFInterface(類庫) 提供雙方通信服務接口/契約,WCFService(類庫) 實現相關服務接口,Hosting(控制台) 服務的宿主程序,WCFClient(控制台) 調用服務的客戶端程序。
- 在WCFInterface中編寫服務接口 :
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ServiceModel; using System.Runtime.Serialization; namespace WCFInterface { [ServiceContract(CallbackContract = typeof(IPrintCallback))] public interface ITestServiceInterface { [OperationContract] int Add(int a, int b); [OperationContract(IsOneWay=true)] void findObjByName(string name); } [DataContract] public class MyObj { [DataMember] public int ID { get; set; } [DataMember] public string Name { get; set; } [DataMember] public int Age { get; set; } } }
- 在WCFInterface中編寫回調接口:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ServiceModel; namespace WCFInterface { public interface IPrintCallback { [OperationContract(IsOneWay=true)] void PrintObj(MyObj obj); } }
- Hosting 需引用WCFInterface與WCFService程序集,Program.cs代碼如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ServiceModel; using System.ServiceModel.Description; using WCFService; using WCFInterface; namespace Hosting { class Program { static void Main(string[] args) { using (ServiceHost host = new ServiceHost(typeof(TestServiceImp))) { host.Opened += host_Opened; host.Open(); Console.Read(); } } static void host_Opened(object sender, EventArgs e) { Console.WriteLine("test service 已啟動"); } } }
- Hosting 根目錄下創建 App.config文件,配置如下:
<?xml version="1.0" encoding="utf-8" ?> <configuration> <!-- 部署服務庫項目時,必須將配置文件的內容添加到 主機的 app.config 文件中。System.Configuration 不支持庫的配置文件。 --> <system.serviceModel> <services> <service name="WCFService.TestServiceImp"> <host> <baseAddresses> <add baseAddress="http://localhost:1234/service/" /> <add baseAddress="net.tcp://localhost:2345/service/" /> </baseAddresses> </host> <!-- Service Endpoints --> <!-- 除非完全限定,否則地址將與上面提供的基址相關 --> <endpoint address="testservice" binding="netTcpBinding" contract="WCFInterface.ITestServiceInterface"> <!-- 部署時,應刪除或替換下列標識元素,以反映 用來運行所部署服務的標識。刪除之后,WCF 將 自動推斷相應標識。 --> <identity> <dns value="localhost"/> </identity> </endpoint> <!-- Metadata Endpoints --> <!-- 元數據交換終結點供相應的服務用於向客戶端做自我介紹。 --> <!-- 此終結點不使用安全綁定,應在部署前確保其安全或將其刪除 --> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/> </service> </services> <behaviors> <serviceBehaviors> <behavior> <!-- 為避免泄漏元數據信息, 請在部署前將以下值設置為 false --> <serviceMetadata httpGetEnabled="TRUE"/> <!-- 要接收故障異常詳細信息以進行調試, 請將以下值設置為 true。在部署前設置為 false 以避免泄漏異常信息 --> <serviceDebug includeExceptionDetailInFaults="TRUE" /> </behavior> </serviceBehaviors> </behaviors> </system.serviceModel> </configuration>
- 啟動Hosting,如圖
- WCFClient 右鍵添加服務引用,地址輸入: http://localhost:1234/service/?singleWsdl .
- WCFClient program.cs中代碼如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ServiceModel; using WCFClient.TestService; namespace WCFClient { class MyCallBack : ITestServiceInterfaceCallback { public void PrintObj(WCFClient.TestService.MyObj obj) { Console.WriteLine("Obj ID:" + obj.ID + " obj name:" + obj.Name + " obj age:" + obj.Age); } } class Program { static void Main(string[] args) { InstanceContext callback = new InstanceContext(new MyCallBack()); TestServiceInterfaceClient client = new TestServiceInterfaceClient(callback); Console.WriteLine(client.Add(1,5)); client.findObjByName("abc"); Console.Read(); } } }
- 結果如圖: