创建Wcf简单实例

本文为新人如何快速入门WCF应用程序案例

1.创建服务端(Server)

建立一个控制台应用程序作为Server,新建一个接口ICase作为服务契约。这个契约接口一会儿也要放到Client端,这样双方才能遵循相同的标准。别忘了添加对System.ServiceModel的引用。

using System;

using System.ServiceModel;

using System.Text;

namespace Server

{

   /// <summary>

   /// 用ServiceContract来标记此接口是WCF的服务契约,可以像WebService一样指定一个Namespace,如果不指定,就是默认的http://tempuri.org

   /// </summary>

   [ServiceContract(Namespace="WCF.Demo")]

   public interface ICase

   {

       /// <summary>

       /// 用OperationContract来标记此方法是操作契约

       /// </summary>

       [OperationContract]

       string HelloWord(string userName);

   }

}

 

针对这个接口建立实现类,这个类才是真正干活的,工作在服务端,不出现在客户端:

using System;

using System.Text;

namespace Server

{

   /// <summary>

   /// 实现IData接口,此处不需要写契约标记

   /// </summary>

   public class Case: ICase

   {

       public string SayHello(string userName)

       {

     //此处可写对应的方法体,实现你的需求,本实例就不写了,直接返回参数吧!

           return userName;

       }

   }

}

 

为工程添加一个App.config文件,这里面要定义与服务发布相关的参数。WCF中常见的做法是用代码写服务逻辑,但是用配置文件来定义服务发布方式,这样做的好处是松散耦合。

<?xmlversion="1.0"encoding="utf-8"?>

<configuration>

<system.serviceModel>

 <!-- 看到services节,就表明这是在定义服务相关的内容 -->

 <services>

 <!-- 定义一个服务,name是契约实现类的全名 -->

   <servicename="Server.DataProvider">

   <!-- 既然要对外提供服务,就要有服务地址,此处定义为 http://localhost:8080/wcf,需要注意,地址总是带着类型标头的 -->

     <host>

       <baseAddresses>

         <addbaseAddress="http://localhost:8080/wcf"/>

       </baseAddresses>

     </host>

     <!-- 定义一下终节点,address一般为空,如果不为空,最终服务地址就是在baseAddress的基础上加上这个address,binding指定为basicHttpBinding,这是最基础的基于http的绑定方式,contract标明这是为哪个契约服务 -->

     <endpoint address=""binding="basicHttpBinding"contract="Server.ICase"/>

   </service>

 </services>

</system.serviceModel>

</configuration>

 

现在一个简单的wcf服务就创建成果了,只剩最后一步了,将服务发布出去:

using System;

using System.ServiceModel;

namespace Server

{

   class Program

   {

       static void Main(string[] args)

       {

           //定义一个ServiceHost,注意参数中要使用契约实现类而不是接口

           using(ServiceHost host = new ServiceHost(typeof(Server.DataProvider)))

           {

               host.Open();

               Console.WriteLine("Service Running ...");

               Console.ReadKey();

               host.Close();

           }

       }

   }

}

 

有人可能会问服务发布到哪去了?没指定地址呀?这是一个初学者容易搞不明白的地方。

是的,此时App.config中的定义就发挥作用了,由于ServiceHost中指定对Server.DataProvider类服务,而App.config中定义了name="Server.DataProvider"的service,其下有endpoint,定义了绑定方式是basicHttpBinding,而http方式的baseAddress只有一个,就是 http://localhost:8080/wcf。

编译运行,屏幕显示Service Running ... 就是正常跑起来了,此时如果用命令行 netstat -ano | findstr "8080" 看一下,应该有如下输出:

  1. TCP    0.0.0.0:8080         0.0.0.0:0          LISTENING      4

  2. TCP    [::]:8080            [::]:0             LISTENING      4

表示我们的程序已经在TCP 8080端口开始监听了。值得注意的是PID是4,这是系统进程而不是我们自己的进程,这说明WCF程序对外提供HTTP服务时,是借用了系统功能(http.sys)。

此时如果我们用浏览器访问一下 http://localhost:8080/wcf,不报错,但是会提示“当前已禁用此服务的元数据发布”,这是由于默认不允许以http get方式获取服务的WSDL,我们不用管它,不影响后面的使用,以后的章节中我们再来看这个问题。

 

2.创建客户端(在项目中添加服务引用可以省去此布,系统会自动在app.config中配置完成,但是需要把address的路径改成服务器路径)

再建立一个控制台应用程序作为Client,把Server中的接口ICase拷过来,因为这是服务契约。

为工程添加一个App.config文件,这里面要定义客户端访问的相关参数,这里我去掉了一些用不上的参数,以保持配置文件简单,防止各位看晕了头。

<?xmlversion="1.0"encoding="utf-8"?>

<configuration>

 <system.serviceModel>

   <!-- 看到client,就表明是客户端设置 -->

   <client>

     <!-- 定义访问时的终节点,name也是随意取的,注意address是Server端发布时指定的baseAddress+endpoint的address,binding也要对应,contract就更不用说了,由于之前把ICase.cs拷过来的时候没有修改命名空间,所以还是Server.IData -->

     <endpointname="DataService"address="http://localhost:8080/wcf"binding="basicHttpBinding"contract="Server.ICase"/>

   </client>

 </system.serviceModel>

</configuration>

然后写代码,来调用Server端发布的HelloWord方法:

using System;

using System.ServiceModel;

using System.ServiceModel.Channels;

namespace Client

{

   class Program

   {

       static void Main(string[] args)

       {

           //客户端访问有多种方式,此处只显示一种

           //利用ChannelFactory的CreateChannel方法创建一个IData的代理对象,其中参数“DataService”就是刚才在App.config中定义的endpoint的名称

           var proxy = new ChannelFactory<Server.ICase>("DataService").CreateChannel();

//调用HelloWord方法

           Console.WriteLine(proxy.HelloWord("WCF"));

//用完后一定要关闭,因为服务端有最大连接数,不关闭会在一定时间内一直占着有效连接

           ((IChannel)proxy).Close();

       }

   }

}

编译运行,屏幕应能正常打印出“参数”。第一个入门demo就搞定了,应该还是比较简单的。只是App.config的配置有些复杂,后面我们会看到,其实也可以不要配置,直接用代码搞定,不过从松散耦合的角度讲不建议这么做。

posted on 2015-11-19 11:07  Andy_陈  阅读(357)  评论(0)    收藏  举报

导航