背景:使用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(); } } }
- 结果如图: