最近由于项目需要,简单研究了一下.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 来实现。

我自己开发过程总结了一下大致以下步骤

  1. 编写类库,定义契约
  2. 编写宿主
  3. 配置宿主
  4. 引用服务
  5. 编写客户端

其中,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的配置,都在客户端引用服务时出现无法访问这样错误,下次我介绍一下我是如何配置的。

 

posted on 2016-09-23 19:57  zooz  阅读(130)  评论(0编辑  收藏  举报