`
fdyang
  • 浏览: 79660 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类
最新评论

(WCF) 示例1:Magic Eight Ball.

阅读更多


实例一: 构建一个简单的WCF Service: MagicEightBall (问问题,自动回答)


首先回顾一下WCF程序集之间的关系,理解WCF Host和Client之间的通信架构


┌────────────────┐                     ┌────────────────┐

│ Client App                             │   (SOAP)       │ WCF Host                            │

│      [ Proxy ]<─────────────────>[WCF Service]                       │

└────────────────┘                     └────────────────┘

            │                                                                   │

     Config File                                                      Config File


实现WCF通信的思路就是: 

创建WCF Service(包括定义Contract和Service,配置Config文件) -> 承载(寄宿)宿主(Host) -> 客户端程序创建Proxy,实现和WCF Service进行通信。

 

具体步骤如下:  

1. 创建Contracts类库,创建WCF Service的接口 IEightBall 。

   1)添加引用(.NET)System.ServiceModel.dll程序集,并引用System.ServiceModel命名空间。

   2)将WCF Service接口标记 [ServiceContract]特性,每个接口成员标记[OperaionContract]特性。



using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.ServiceModel;

namespace Contracts
{
    //为了使接口称为WCF Services接口,必须用[ServiceContract]特性加以标记
    [ServiceContract]
    public interface IEightBall
    {
        //Ask one question ,and then get an answer.
		//WCF框架中使用的方法必须用[OperationContract]特性来修饰。
        [OperationContract]        
        string ObtainAnswerToQuestion(string userQuestion); 
    }
}

 



2. 创建Services类库,对Service接口IEightBall进行实现。

   1)添加引用Contracts Project,并在代码中引用Contracts命名空间。

   2)定义对接口实现的具体的内容。



using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Contracts;

namespace Services
{
    public class EightBallService : IEightBall 
    {
        //Constractor , just display message in Host.
        public EightBallService()
        {
            Console.WriteLine("The 8-ball awaits your question... ");
        }	

        //Services method for interface 
        public string ObtainAnswerToQuestion(string userQuestion)
        {
            string[] answers = { "Future Uncertain", "Yes", "No", "Hazy", "Ask again later", "Definitely" };

            //Return random answer.
            Random r = new Random();
            return answers[r.Next(answers.Length)];
        }
    }
}

 


3. 创建Host控制台程序,承载(寄宿)WCF Service (产品级的服务一般用Windows Service 或 IIS 虚拟目录承载)


   在创建WCF Service的Host时,需要决定在代码中定义必要的承载逻辑,还是配置相关的Config文件。 配置Config文件的好处在于Host可以改变底层的运行方式而不用重新编译和部署可执行文件。


   构建WCF Service的Host的一般步骤为: 

   (I)在Host的配置文件中,定义所承载的WCF Service 的 终结点(Endpoint)。

   (II)通过编程使用ServiceHost类型去提供 Endpoint所提供的Service类型。

   (III)确保Host保持运行状态,以处理所受到的客户端请求。(显然,Windows Service 或 IIS 不需要这一步 )


   具体实现如下:

   1)向当前项目中添加一个Application Configuration File (App.conifg). 在App.config文件中创建ABC ,

     在WCF的世界中,终结点(Endpoint)是表示A(地址),B(绑定),C(契约)的一个包装。

在XML中,终结点使用<endpoint>元素,和address,binding,contract 元素进行表达。



<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <services>
      <service name="Services.EightBallService">
        <endpoint address ="http://localhost:8080/EightBallService"
                  binding ="basicHttpBinding"
                  contract ="Contracts.IEightBall"/>
      </service>
    </services>
  </system.serviceModel>
</configuration>

 


   2)针对ServiceHost类型进行编程。创建ServiceHost实例,在运行时,这个对象会自动读取Host 中*.config文件中<system.serviceModel>元素中的数据来检测正确的地址,绑定类型和契约,然后创建必要的管道。

   2.1)添加对System.ServiceModel.dll 和 本例中 Services project (即Services.dll) 的引用。

   2.2)代码中引用System.ServiceModel , Services 命名空间

   2.3)启用元数据交换

       - 元数据交换(MEX)是一个WCF Service Behaviors,可以指定它微调WCF运行库如何处理我们的Service

  - MEX行为会通过HTTP-GET拦截任何元数据请求。如果希望用svcutil.exe或者VS2010来自动创建客户端代理的*.config文件,必须启用MEX。

  修改Host的App.config文件如下:

  


<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <services>
      <service name="Services.EightBallService"
               behaviorConfiguration ="MEXBehavior">
        <endpoint address=""
                  binding="basicHttpBinding"
                  contract="Contracts.IEightBall"/>

        <!-- Enable MEX endpoint-->
        <endpoint address="mex"
                  binding="mexHttpBinding"
                  contract="IMetadataExchange"/>

        <!-- Let MEX know the address of Service-->
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8080/Services/EightBallService"/>
          </baseAddresses>
        </host>
      </service>
    </services>

    <!-- Define behavior of MEX-->
    <behaviors>
      <serviceBehaviors>
        <behavior name="MEXBehavior">
          <serviceMetadata httpGetEnabled="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>

  </system.serviceModel>
</configuration>

 

  

Host代码如下:



using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.ServiceModel;
using Services;

namespace TestServiceHost
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(" Console Based WCF Host ");
            using (ServiceHost serviceHost = new ServiceHost(typeof(EightBallService)))
            {
                //Open host and keep listenning from client. 
                serviceHost.Open();

                //Display host control application windows, and don't exist unless Enter key is pressed.
                Console.WriteLine(" The service is ready. Press the Enter key to terminate service. ");
                Console.ReadLine();
            }
        }
    }
}

 

运行这个应用程序后(run as administrator),宿主在内存中随时准备接受从远程客户端发来的请求。

可以用Web浏览器来查看元数据描述。http://localhost:8080/Services/EightBallService



补充1: <system.serviceModel>元素的细节


<system.serviceModel>
  <behaviors></behaviors>        <!-- 进一步限定Host,Service或Client端的功能。-->
  <client></client>              <!-- 包含客户端来连接到Service的endpoint列表。-->
  <commonBehaviors></commonBehaviors>       <!-- 定义了允许WCF和COM互操作的COM契约-->
  <diagnostics></diagnostics>    <!-- 包含WCF诊断特新的设置,可以启用或禁用跟踪,性能计数器,和WMI提供程序,并且可以增加自定义消息过滤器-->
  <comContracts></comContracts>  <!-- 这个元素只能在machine.config文件中进行设置,可以用于定义某个机器所有的WCF的行为-->
  <services></services>          <!-- 包含了从Host公开的WCF Service的集合 -->
  <bindings></bindings>          <!-- 允许我们微调WCF提供的绑定如basicHttpBinding和netMsmqBing等-->
</system.serviceModel>

 


4. 创建一个控制台项目,构建WCF Client端应用程序。 

   1)首先需要创建客户端代理(proxy)  (注:之前需要使Host程序保持运行,即使WCF Service保持运行状态)

   方法一: 使用svcutil.exe 生成代理代码

   svcutil http://localhost:8080/EightBallService/out:myProxy.cs /config:app.cofig


   方法二: 使用VS2010生成代理代码。

   1.1) 在Client控制台项目中,Add Service Reference。然后在Address里面输入Service的Uri: http://localhost:8080/EightBallService

   1.2) 点击go查看Service 描述。命名为 EightBallServiceReference 后保存退出。

        - 工具会自动生成客户端的代理类EightBallClient代码。

   2)编写客户端控制台代码



using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

// Proxy location
using Client.EightBallServiceReference;

namespace Client
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(" Ask the Magic 8 Ball . \n");

            using (EightBallClient ball = new EightBallClient())
            {
                Console.Write("Your questoin:");
                string question = Console.ReadLine();
                string answer = ball.ObtainAnswerToQuestion(question);
                Console.WriteLine("8-ball syas:{0}", answer);
            }
            Console.ReadLine();
        }
    }
}

 


至此,我们在Client端运行Client.exe程序,就可以通过Service代理类来运行WCF Service 中的方法了。 实现了Client端和Server端的通信。

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics