zoukankan      html  css  js  c++  java
  • (WCF)示例一: 构建一个简单的WCF Service: MagicEightBall

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

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

    实现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]特性。

    C#代码 
    1. <span style="">using System;  
    2. using System.Collections.Generic;  
    3. using System.Linq;  
    4. using System.Text;  
    5.   
    6. using System.ServiceModel;  
    7.   
    8. namespace Contracts  
    9. {  
    10.     //为了使接口称为WCF Services接口,必须用[ServiceContract]特性加以标记  
    11.     [ServiceContract]  
    12.     public interface IEightBall  
    13.     {  
    14.         //Ask one question ,and then get an answer.  
    15.         //WCF框架中使用的方法必须用[OperationContract]特性来修饰。  
    16.         [OperationContract]          
    17.         string ObtainAnswerToQuestion(string userQuestion);   
    18.     }  
    19. }</span>  

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

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

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

    C#代码 
    1. <span style="">using System;  
    2. using System.Collections.Generic;  
    3. using System.Linq;  
    4. using System.Text;  
    5.   
    6. using Contracts;  
    7.   
    8. namespace Services  
    9. {  
    10.     public class EightBallService : IEightBall   
    11.     {  
    12.         //Constractor , just display message in Host.  
    13.         public EightBallService()  
    14.         {  
    15.             Console.WriteLine("The 8-ball awaits your question... ");  
    16.         }     
    17.   
    18.         //Services method for interface   
    19.         public string ObtainAnswerToQuestion(string userQuestion)  
    20.         {  
    21.             string[] answers = { "Future Uncertain""Yes""No""Hazy""Ask again later""Definitely" };  
    22.   
    23.             //Return random answer.  
    24.             Random r = new Random();  
    25.             return answers[r.Next(answers.Length)];  
    26.         }  
    27.     }  
    28. }  
    29. </span>  

    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代码 
    1. <span style=""><?xml version="1.0" encoding="utf-8" ?>  
    2. <configuration>  
    3.   <system.serviceModel>  
    4.     <services>  
    5.       <service name="Services.EightBallService">  
    6.         <endpoint address ="http://localhost:8080/EightBallService"  
    7.                   binding ="basicHttpBinding"  
    8.                   contract ="Contracts.IEightBall"/>  
    9.       </service>  
    10.     </services>  
    11.   </system.serviceModel>  
    12. </configuration></span>  

       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代码 
    1. <span style=""><?xml version="1.0" encoding="utf-8" ?>  
    2. <configuration>  
    3.   <system.serviceModel>  
    4.     <services>  
    5.       <service name="Services.EightBallService"  
    6.                behaviorConfiguration ="MEXBehavior">  
    7.         <endpoint address=""  
    8.                   binding="basicHttpBinding"  
    9.                   contract="Contracts.IEightBall"/>  
    10.   
    11.         <!-- Enable MEX endpoint-->  
    12.         <endpoint address="mex"  
    13.                   binding="mexHttpBinding"  
    14.                   contract="IMetadataExchange"/>  
    15.   
    16.         <!-- Let MEX know the address of Service-->  
    17.         <host>  
    18.           <baseAddresses>  
    19.             <add baseAddress="http://localhost:8080/Services/EightBallService"/>  
    20.           </baseAddresses>  
    21.         </host>  
    22.       </service>  
    23.     </services>  
    24.   
    25.     <!-- Define behavior of MEX-->  
    26.     <behaviors>  
    27.       <serviceBehaviors>  
    28.         <behavior name="MEXBehavior">  
    29.           <serviceMetadata httpGetEnabled="true"/>  
    30.         </behavior>  
    31.       </serviceBehaviors>  
    32.     </behaviors>  
    33.   
    34.   </system.serviceModel>  
    35. </configuration>  
    36. </span>  

       

    Host代码如下:

    C#代码 
    1. <span style="">using System;  
    2. using System.Collections.Generic;  
    3. using System.Linq;  
    4. using System.Text;  
    5.   
    6. using System.ServiceModel;  
    7. using Services;  
    8.   
    9. namespace TestServiceHost  
    10. {  
    11.     class Program  
    12.     {  
    13.         static void Main(string[] args)  
    14.         {  
    15.             Console.WriteLine(" Console Based WCF Host ");  
    16.             using (ServiceHost serviceHost = new ServiceHost(typeof(EightBallService)))  
    17.             {  
    18.                 //Open host and keep listenning from client.   
    19.                 serviceHost.Open();  
    20.   
    21.                 //Display host control application windows, and don't exist unless Enter key is pressed.  
    22.                 Console.WriteLine(" The service is ready. Press the Enter key to terminate service. ");  
    23.                 Console.ReadLine();  
    24.             }  
    25.         }  
    26.     }  
    27. }  
    28. </span>  

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

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

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

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

    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)编写客户端控制台代码

    C#代码 
    1. <span style="">using System;  
    2. using System.Collections.Generic;  
    3. using System.Linq;  
    4. using System.Text;  
    5.   
    6. // Proxy location  
    7. using Client.EightBallServiceReference;  
    8.   
    9. namespace Client  
    10. {  
    11.     class Program  
    12.     {  
    13.         static void Main(string[] args)  
    14.         {  
    15.             Console.WriteLine(" Ask the Magic 8 Ball . \n");  
    16.   
    17.             using (EightBallClient ball = new EightBallClient())  
    18.             {  
    19.                 Console.Write("Your questoin:");  
    20.                 string question = Console.ReadLine();  
    21.                 string answer = ball.ObtainAnswerToQuestion(question);  
    22.                 Console.WriteLine("8-ball syas:{0}", answer);  
    23.             }  
    24.             Console.ReadLine();  
    25.         }  
    26.     }  
    27. }</span>  

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

  • 相关阅读:
    [Multimedia] 下载 m3u8 格式视频
    [Multimedia] 合并两个 MP4 文件
    [Multimedia] FLV 相关分析工具
    [Android] 从 logcat 日志中获取设备的 mac 地址信息
    [Android Tips] 33. Lottie 在 RecyclerView onBindViewHolder 中 playAnimation 不生效
    [Multimedia] 旋转 MP4 视频方向
    [Jenkins] Jenkins changes 显示 git log 乱码解决
    [Jenkins] Jenkins 时区设置
    [Gradle] 解决高德 jar 包打包到 aar 后 jar 包中的 assets 内容丢失
    [Gradle] 发布 library 到本地 maven 仓库
  • 原文地址:https://www.cnblogs.com/fdyang/p/2858704.html
Copyright © 2011-2022 走看看