最近由于项目需要,简单研究了一下.NET WCF编程。
首先,简单说下WCF是什么,WCF 本质上,是一种开发框架。它用来开发类似COM+ 、WEB SERVICE 这样“远程方法调用” 功能。
普通情况想,一个进程中,A模块调用B模块的方法。
有了COM+ 、Webservice 这些,可以实现A进程 调用 B进程的方法。 更好的是,A,B可以不在同一个机器上。WCF就用来开发这样的“功能”
WCF 比 COM+ WebService 灵活,(高效不知道,没有实际案例测试)
- 能在http\tcp\pipe\msmq 之间灵活切换。
- 可以注入到应用程序、windows服务、web服务中。(以webservice为例,它似乎只能在web容器中发挥作用。wcf 可以以一个exe为宿主。)
我打算从一个简单的例子开始,分别用http 和 tcp 来实现。
我自己开发过程总结了一下大致以下步骤
- 编写类库,定义契约
- 编写宿主
- 配置宿主
- 引用服务
- 编写客户端
其中,3,4 步骤有很强的关联关系。
下面我就用VS2013 .net framework 4 来实现一个简单的基于http协议的WCF
我们此次目标是 实现,提供加法运算、 问候语功能的服务,宿主我们用一个控制台(要改IIS 或者 windows服务,我们后面会涉及到)
1 编写类库
首先,用C#语言新建一个类库工程
处理一些基本的命名规范
添加 Sysmte.ServiceModel程序集
同时添加 using System.ServiceModel;
接着,需要定义契约和接口,代码和注释如下
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ServiceModel; namespace WCF_Simple_Lib { //1 先编写这样的代码,表示一个服务契约。关于它的细节我们以后再研究 [ServiceContract] //2 定义一个接口, public interface IWCF_Simple { //3 这个接口要求实现一个Add加法,为了让这个方法被远程调用,需要[OperationContract] // 同样的,关于它的细节我们以后研究 [OperationContract] int Add(int x,int y); //4 每个对外的接口都需要加入OperationContract约束 [OperationContract] String Hello(String yourName); } //5 实现这个接口 public class WCF_Simple_Impress:IWCF_Simple { public int Add(int x,int y) { return x+y; } public String Hello(String yourName) { return String.Format("Hello! {0}",yourName);; } } public class WCF_Simple1_Lib { } }
编译,得到 WCF_Simple_Lib.dll,第一步结束
2,编写宿主
再新建一个控制台工程,同时引用System.ServiceModel 程序集 和 我们在第一个步骤中编译得到的WCF_Simple_Lib.dll
添加一个应用程序配置文件 App.config
然后生成一下。这样加载类库,为一步做准备。
继续下一步,最后输入访问host的http地址。
VS 自动填写好APP.CONFIG的内容
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.serviceModel> <services> <service name="WCF_Simple_Lib.WCF_Simple_Impress"> <endpoint address="http://127.0.0.1:8090/wcfsimplehost" binding="basicHttpBinding" bindingConfiguration="" contract="WCF_Simple_Lib.IWCF_Simple" /> </service> </services> </system.serviceModel> </configuration>
事实上到这一步,这个服务已经配置完了。但是,如果仅仅这样配置,我们无法引用这个服务。所以还有一些工作要做。
和我们之前配置第一个终结点,时指定的地址一样写。
点击保存,我们得到这样的APP.CONFIG
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.serviceModel> <behaviors> <serviceBehaviors> <behavior name="NewBehavior0"> <serviceMetadata httpGetEnabled="true" /> </behavior> </serviceBehaviors> </behaviors> <services> <service behaviorConfiguration="NewBehavior0" name="WCF_Simple_Lib.WCF_Simple_Impress"> <endpoint address="" binding="basicHttpBinding" bindingConfiguration="" contract="WCF_Simple_Lib.IWCF_Simple" /> <endpoint address="mex" binding="mexHttpBinding" bindingConfiguration="" contract="IMetadataExchange" /> <host> <baseAddresses> <add baseAddress="http://127.0.0.1:8090/wcfsimplehost" /> </baseAddresses> </host> </service> </services> </system.serviceModel> </configuration>
这样,配置,我们的服务就可以被其他的客户端引用了!
服务端编码
配置的步骤有点多,现在我们可以服务单host的代码了!
using System; using System.Collections.Generic; using System.Linq; using System.Text; using WCF_Simple_Lib; //1 引用自己编写的契约类库 using System.ServiceModel; //2 引用ServiceModel类库 namespace WCF_Simple_Host { class Program { static void Main(string[] args) { Console.WriteLine("***服务准备启动...***"); //3 实例化一个ServiceHost,它的服务行为,都读配置文件,也可以通过编码设置 // 我们以后再研究这些细节。 using (ServiceHost host = new ServiceHost(typeof(WCF_Simple_Impress))) { //4 打开服务,让服务处于侦听状态。 host.Open(); Console.WriteLine("***服务运行中...***"); Console.ReadKey(); } } } }
生成这个Host工程,然后运行。如果全面配置都正确的话
会到这样的命令行界面
同时在浏览器中输入
http://127.0.0.1:8090/wcfsimplehost
会看到这样的信息,说明我们的服务已经开始运行了。
客户端编写
终于可以编写客户端了,客户端相对来说
首先,停止在vs中运行,我们的servicehost, 改用管理员身份,在运行exe文件。
在VS中添加一个新的控制台工程,并添加服务引用
点确定之后,VS会自动的帮我们产生一个叫WCF_SimpleClient 的代理类。
(VS之所以能感知到这个服务,是因为我们定义了 mex 终结点,如果没有定义,就无法感知,也就无法帮我们产生代理类,那么就需要我们自己手工去写代理类)
做完这些之后,我们给客户端编写代码
using System; using System.Collections.Generic; using System.Linq; using System.Text; using WCF_Client_Test.ServiceReference1; //1 引用代理类 namespace WCF_Client_Test { class Program { static void Main(string[] args) { //2 可以访问到WCF_SimpleClient 这样命名的代理类,更多细节我们以后研究 WCF_SimpleClient client = new WCF_SimpleClient(); //3 很本地类一样调用它的Add 和 Hello方法,其实是调用了远程服务器上的方法 Console.WriteLine("101+120={0}", client.Add(101, 120)); Console.WriteLine("Service said:{0}",client.Hello(" 张三 ")); Console.ReadKey(); } } }
确保,WCF_Service_Host 这个应用是启动的,运行客户端程序
会按到一下效果
说明我们调用远程方法成功了。
至此,我们的第一个WCF SIMPLE 就成功了。留下很多细节,我们后续会逐步研究,下一次我们来配置一个基于TCP 的WCF
CSDN 和一些搜索出来的基于tcp的配置,都在客户端引用服务时出现无法访问这样错误,下次我介绍一下我是如何配置的。