zoukankan      html  css  js  c++  java
  • [Solution] 一步一步WCF(1) 快速入门

      Windows Communication Foundation(WCF)是由微软开发的一系列支持数据通信的应用程序框架,可以翻译为Windows 通讯开发平台。整合了原有的windows通讯的 .net Remoting,WebService,Socket的机制,并融合有HTTP和FTP的相关技术。是Windows平台上开发分布式应用最佳的实践方式。

      安装:在.net framework 3.0的时候已经内置了WCF。

      由于WCF的服务不能孤立地存在,需要寄宿于一个运行着的进程中,我们把承载WCF服务的进程称为宿主。在本节将介绍2种服务寄宿服务,并分别通过Code和Config的方式为WCF服务绑定endpoint:

    自我寄宿

    1.建立项目

    • Service一个控制台应用,实现对wcf服务的寄宿,该项目引用System.ServiceMode程序集。(WCF框架的绝大部分实现和API定义在该程序集中)
    • Client一个控制台应用,实现对服务的调用端,该项目引用System.ServiceMode程序集。(生成的代理类继承自该程序集)

    2.创建契约(contract)

      WCF包含四种类型的契约:服务契约、数据契约、消息契约和错误契约。这里所指服务契约,用来声明服务的所有操作。

      要使一个接口成为一个契约,需要为其贴上特性标签。

    using System.ServiceModel;
    
    namespace Service
    {
        [ServiceContract]
        public interface ICar
        {
            [OperationContract]
            string Run(int distance);
        }
    }
    

      

    3.实现服务

      实现接口方法即可

    namespace Service
    {
        public class CarService : ICar
        {
            public string Run(int distance)
            {
                return "行驶了" + distance;
            }
        }
    }

    4.开始寄宿

      WCF采用终结点的通信方式。终结点包括Address,Binding,Contract,简称ABC。

    Address:  指定wcf的location

    Binging:  指定传输协议。(tcp http msmq等)

    Contract:  指定服务的Behavior。

    using System;
    using System.ServiceModel;
    
    namespace Service
    {
        class Program
        {
            static void Main(string[] args)
            {
                using (var host = new ServiceHost(typeof(CarService)))
                {
                    //指定服务的终结点,分别指定Contract,Binding,Address
                    host.AddServiceEndpoint(typeof(ICar), new BasicHttpBinding(), "http://localhost:10000/Car");
                    host.Open();
                    Console.WriteLine("服务启动成功");
                    Console.Read();
                }
            }
        }
    }

    (已管理员身份启动Service.exe)

    服务以及寄宿成功,那我们怎么调用呢。实际上,这样的方式是无法被调用的。客户端引用的地址是服务的元数据。所以我们需要把服务的元数据暴露出来。

    using System;
    using System.ServiceModel;
    using System.ServiceModel.Description;
    
    namespace Service
    {
        class Program
        {
            static void Main(string[] args)
            {
                using (var host = new ServiceHost(typeof(CarService)))
                {
                    if (host.Description.Behaviors.Find<ServiceMetadataBehavior>() == null)
                    {
                        //服务的元数据 允许Get方式从下面的Url中获取
                        var behavior = new ServiceMetadataBehavior
                        {
                            HttpGetEnabled = true,
                            HttpGetUrl = new Uri("http://localhost:10000/Car/Metadata")
                        };
                        host.Description.Behaviors.Add(behavior);
                    }
                    //指定服务的终结点,分别指定Contract,Binding,Address
                    host.AddServiceEndpoint(typeof(ICar), new BasicHttpBinding(), "http://localhost:10000/Car");
                    host.Opened += (o, e) => Console.WriteLine("服务启动成功");
                    host.Open();
                    Console.Read();
                }
            }
        }
    }

    5.服务的调用

      服务的调用有2种方式,VS引用服务生成代理类,Code自定义代理类(需要保证Endpoint完全一致)。

    Code自定义代理类:

    using System;
    using System.ServiceModel;
    
    namespace Client
    {
        class Program
        {
            static void Main(string[] args)
            {
                //一致的终结点
                using (var channelFactory = new ChannelFactory<ICar>(new BasicHttpBinding(), "http://localhost:10000/Car"))
                {
                    //手动创建代理类
                    var proxy = channelFactory.CreateChannel();
                    Console.WriteLine(proxy.Run(3));
                }
                Console.Read();
            }
        }
    }
    

    这里面的ICar(Contract),并非一定和wcf服务的ICar完全一致(指命名空间,所在程序集名称),只需方法签名一致即可。(由于是Contract仍需对应的特性)

    using System.ServiceModel;
    
    namespace Client
    {
        [ServiceContract]
        interface ICar
        {
            [OperationContract]
            string Run(int distance);
        }
    }
    

    在管理员运行前面的Service.exe基础上,运行Client.exe。

    IIS寄宿

    1.建立项目

    2.文件结构

    3.svc文件

    svc文件相当于asmx文件,通过一个必须指令Service,指定具体的服务。如Service="WcfService.Service1"

    在vs中,浏览器查看svc文件,svc的地址就是服务的地址。svc的地址+?wsdl是服务描述的地址。

    4.服务的调用

    和自我寄宿的服务类似,只用将Address改成svc的地址即可。 

    注意,在新建svc文件的时候,vs会自动修改Web.config文件。(用来指定服务的元数据暴露行为)

    <system.serviceModel>
        <behaviors>
          <serviceBehaviors>
            <behavior name="">//指定默认的behavior
              <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
            </behavior>
          </serviceBehaviors>
        </behaviors>
      </system.serviceModel>
    

    Config

    以上基本均采用Code的方式实现WCF,实际上WCF非常灵活,一般都采用Config方式。或者Config+Code(都会生效)。

    wcf的配置涉及到2种,服务的发布,服务的调用。

    发布:

    <system.serviceModel>
        <behaviors>
          <serviceBehaviors>
            <behavior name="meta">
              <serviceMetadata httpGetEnabled="true" httpGetUrl="http://localhost:10001/Car/Metadata"/>
            </behavior>
          </serviceBehaviors>
        </behaviors>
        <services>
          <service name="Service.CarService" behaviorConfiguration="meta">
            <endpoint address="http://localhost:10001/Car" binding="wsHttpBinding" contract="Service.ICar"></endpoint>
            <endpoint address="http://localhost:10001/Car2" binding="wsHttpBinding" contract="Service.ICar"></endpoint>
          </service>
        </services>
      </system.serviceModel>

    调用:

    <system.serviceModel>
        <client>
          <endpoint name="car" address="http://localhost:10001/Car" binding="wsHttpBinding" contract="Client.ICar"></endpoint>
        </client>
      </system.serviceModel>
    

    当调用端采用配置方式的时候,代码改成如下方式调用。(配置中name用来区分不同的endpoint,代码中也使用对应的name创建信道栈Channel)

    using System;
    using System.ServiceModel;
    
    namespace Client
    {
        class Program
        {
            static void Main(string[] args)
            {
                using (var cf = new ChannelFactory<ICar>("car"))
                {
                    Console.WriteLine(cf.CreateChannel().Run(3));
                    Console.Read();
                }
            }
        }
    }
    

    上述内容概述了wcf Code和Config2种方式。在实际开发中,可以更简单通过vs的引用服务生成代理类,配置wcf服务工具修改*.config。本文就不再赘述了。

    代码下载:等待整理

    本文作者:Never、C

    本文链接:http://www.cnblogs.com/neverc/p/4682394.html

  • 相关阅读:
    Spring总结(三)
    lucene全文检索
    知识点
    postman本地测试post接口
    第一份任务,写接口验证接口写文档
    spring Date JPA的主要编程接口
    springmvc之格式化要显示的小数或者日期。
    限制action所接受的请求方式或请求参数
    正则表达式映射
    Url通配符映射
  • 原文地址:https://www.cnblogs.com/neverc/p/4682394.html
Copyright © 2011-2022 走看看