WCF学习—我的第一个WCFDemo

在VS2010里建立一个最简单的WCF的Demo

先介绍一些基本概念:

1.体系中的角色。

在WCF的结构中,至少应该有两个角色:服务端和客户端。服务端公开一个或多个服务,客户端访问这些服务以获得相应的逻辑。WCF的服务必须有宿主,随宿主一起启动后,客户端才可以访问到(本文就将WCF服务寄宿到Console程序中)。

2.服务(Service)和操作(Operation)

服务端公开了一个或多个服务(通俗点讲就是接口),每个服务都拥有一个或多个操作(接口方法),客户端通过调用服务的操作来获得服务提供的逻辑。所有标记为 [ServiceContract] 属性(需添加System.ServiceModel引用)的接口都表示该接口是一个服务协定,所有标记为 [OperationContract] 属性的方法都表示该方法是一个操作协定,服务协定和操作协定是可以被客户端调用到的,没有这些标记的接口和方法,服务端本地当然还可以用,但是客户端就访问不到了。

3. 终结点(EndPoint)

终结点包括三个组成部分,即”A","B","C"

A(Address):英文理解为"地址",在计算机中是通过一个URI唯一地址标识,通过这个地址我们可以找到我们要调用的WCF服务。

  A解决了:Where to locate the WCF Service?

B(Binding):英文理解为"捆绑,绑定", Binding实现在Client和Service通信的所有底层细节。如:我们在客户端与服务端传输的时候采用的是什么样的编码,XML?Text?二进制?...采用哪种传输协议进行传输,TCP?Http?以及采用什么样的机制解决安全问题,SSL?加密?...

  B解决了:How to communicate with service?

C(Contract):英文理解为"合同",合同是什么?告诉我们哪些事能做,如些事不能做。 Contract的主要的作用是暴露某个WCF Service所提供的所有有效的方法。Contract实际上是把每个方法的转化成为相对应的消息。

  C解决了:What functionalities do the Service provide?

4.元数据(Metadata)

现在服务端公开了服务,客户端循着正确的终结点,持着正确的绑定找到了服务端,此时服务端笑而不语,客户端不知所措,因为客户端根本不知道服务端公布了那些服务、操作、数据。客户端一个调用也写不出来。虽然客户端不需知道服务和操作的具体实现细节,但是它必须知道服务的接口描述(或类型描述)、操作的方法签名,数据的类描述,这些描述就叫做元数据,服务端必须通过某种方法把元数据交给客户端,这种方法叫做元数据交换(Metadata Exchange)。


服务端

一:新建控制台应用程序,命名WcfDemo

二:在Program.cs中创建服务协定和实现服务协定

    [ServiceContract]
    public interface IService
    {
        [OperationContract]
        string GetMessage();
    }

    public class Service1 : IService
    {
        public string GetMessage()
        {
            string address = OperationContext.Current.Channel.LocalAddress.ToString();
            return string.Format("来自 Service1,地址:{0}", address);
        }
    }
    public class Service2 : IService
    {
        public string GetMessage()
        {
            string address = OperationContext.Current.Channel.LocalAddress.ToString();
            return string.Format("From Service2,Address:{0}", address);
        }
    }

三:添加App.config,修改配置信息

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <services>
      <!--name="命名空间.服务实现类名" behaviorConfiguration=下面behavior的name,或者同时省略-->
      <service name="WcfDemo.Service1" behaviorConfiguration="WcfBehavior">
        <host>
          <baseAddresses>
            <!--可以写多个baseAddress,但每种传输协议只能定义一个baseAddress。HTTP的baseAddress同时是service对外发布服务说明页面的URL-->
            <add baseAddress="http://localhost:9999/WcfDemo/Service1"/>
            <add baseAddress="net.tcp://localhost:8888/WcfDemo/Service1"/>
          </baseAddresses>
        </host>
        <!--address不可重复,包括不可以有两个为空
            address可以为空,则服务地址为baseAddress
            address可以为相对地址,则服务地址为baseAddress+address,
            address可以为绝对地址,则服务地址为address
            binding有很多种,wsHttpBinding是基于http协议的,netTcpBinding,mexTcpBinding是基于tcp协议的,其他的待学习
            contract="命名空间.服务接口类名"-->
        <!--多个终结点就表示有多个路径可以指向服务地址,条条大路通罗马的意思
            但是在客户端创建Client类时,必须指定endpointConfigurationName-->
        <endpoint address="Service_CH1" binding="wsHttpBinding" contract="WcfDemo.IService"/>
        <endpoint address="Service_CH2" binding="netTcpBinding" contract="WcfDemo.IService"/>
        <!--每个终结点对应相应的协议,若没有此终结点,则在添加服务引用的时候搜不到,这里不能用netTcpBinding-->
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
        <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange"/>
      </service>
      <service name="WcfDemo.Service2" behaviorConfiguration="WcfBehavior">
        <host>
          <baseAddresses>    
            <!--因为寄宿于同一个程序,所以相同的传输协议,端口可以共用-->
            <add baseAddress="http://localhost:9999/WcfDemo/Service2"/>
            <add baseAddress="net.tcp://localhost:8888/WcfDemo/Service2"/>
          </baseAddresses>
        </host>
        <endpoint address="Service_EN1" binding="wsHttpBinding" contract="WcfDemo.IService"/>
        <endpoint address="Service_EN2" binding="mexTcpBinding" contract="WcfDemo.IService"/>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
        <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange"/>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="WcfBehavior">
          <serviceMetadata httpGetEnabled="false"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>

四:修改Main方法

        static void Main(string[] args)
        {
            try
            {
                ServiceHost host1 = new ServiceHost(typeof(Service1));
                host1.Open();
                ServiceHost host2 = new ServiceHost(typeof(Service2));
                host2.Open();
            }
            catch (Exception)
            {
                throw;
            }
            Console.WriteLine("服务已开启");
            Console.ReadKey();
        }
四:编译项目,运行(注意需用管理员身份运行)


可在浏览器输入wcf服务地址:http://localhost:9999/WcfDemo/Service1


说明服务启动成功。

客户端

一:新建控制台应用程序,命名WcfClient

二:右键“引用”,选择“添加服务引用


地址栏可以输入http://localhost:9999/WcfDemo/Service1,net.tcp://localhost:8888/WcfDemo/Service1中的任何一个,指向同一个WCF服务。然后更改命名空间WcfSvc1,点击确定。

因为有两个Service,再添加一个WcfSvc2。

三:添加服务引用后,自动生成配置文件app.config,生成四个endpoint,分别对应客户端的四个endpoint

        <client>
            <endpoint address="http://localhost:9999/WcfDemo/Service1/Service_CH1"
                binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IService"
                contract="WcfSvc1.IService" name="WSHttpBinding_IService">
                <identity>
                    <userPrincipalName value="***" />
                </identity>
            </endpoint>
            <endpoint address="net.tcp://localhost:8888/WcfDemo/Service1/Service_CH2"
                binding="netTcpBinding" bindingConfiguration="NetTcpBinding_IService"
                contract="WcfSvc1.IService" name="NetTcpBinding_IService">
                <identity>
                    <userPrincipalName value="***" />
                </identity>
            </endpoint>
            <endpoint address="http://localhost:9999/WcfDemo/Service2/Service_EN1"
                binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IService1"
                contract="WcfSvc2.IService" name="WSHttpBinding_IService1">
                <identity>
                    <userPrincipalName value="***" />
                </identity>
            </endpoint>
            <endpoint address="net.tcp://localhost:8888/WcfDemo/Service2/Service_EN2"
                binding="netTcpBinding" bindingConfiguration="MetadataExchangeTcpBinding_IService"
                contract="WcfSvc2.IService" name="MetadataExchangeTcpBinding_IService" />
        </client>
四:修改Main方法

        static void Main(string[] args)
        {
            WcfSvc1.ServiceClient client11 = new WcfSvc1.ServiceClient("WSHttpBinding_IService");
            Console.WriteLine(client11.GetMessage());
            WcfSvc1.ServiceClient client12 = new WcfSvc1.ServiceClient("NetTcpBinding_IService");
            Console.WriteLine(client12.GetMessage());
            WcfSvc2.ServiceClient client21 = new WcfSvc2.ServiceClient("WSHttpBinding_IService1");
            Console.WriteLine(client21.GetMessage());
            WcfSvc2.ServiceClient client22 = new WcfSvc2.ServiceClient("MetadataExchangeTcpBinding_IService");
            Console.WriteLine(client22.GetMessage());
            Console.Read();
        }

因为一个WCF服务有两个endpoint,所以实例化Client时需指定endpoint的name;若只有一个endpoint,则实例化时可省去此参数。

五:运行程序



至此,WCF程序完成。



参考博文:

1.宋业飞的专栏,老老实实学习WCF

http://blog.csdn.net/songyefei/article/details/7363296

2.Lullaby's Blog,WCF学习总结

http://blog.csdn.net/fangxing80/article/details/6106228



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值