zoukankan      html  css  js  c++  java
  • 初识.net WCF

    WCF, Windows Communication Foundation 是.net一个基于服务的通信框架。
    我所理解的基于服务,是指采用客户端-服务端模式提供的服务。

    WCF的前身应该是web service,WCF作为继承者,除了web service的功能外,提供了更多的配置选项。
    服务端与客户端之间的交互,不仅仅是HTTP,可以是其他的通信机制,比如MSMQ。

    与web service类似,WCF的创建,也比较依赖vs工具进行搭建,自己做不是说做不了,而是麻烦很多。
    在这里简单记录一个WCF服务端和客户端的例子。

    服务端

    WCF服务端提供各种功能供客户端调用/通信。
    wcf服务端分为两部分,服务内容,和宿主。

    WCF服务提供内容简单认为有ABC三部分,即

    • A, Address,服务提供地址
    • B, Binding, 服务提供的的协议
    • C, Contract,服务内容格式

    服务内容

    web service的服务,一般来说是一个标记有WebServiceAttribute的类;
    而WCF的服务,是一个带有ServiceContractAttribute接口的类库,这也就是所谓的C-Contract,它定义的是服务应用侧的数据格式,服务接口。

    接口对应的实现,则没有特殊的标记。

    接口

    这里是用的MS官网上的WCF服务作为例子

     [ServiceContract]
        public interface ICalculator
        {
            [OperationContract]
            double Add(double n1, double n2);
    
            [OperationContract]
            double Subtract(double n1, double n2);
    
            [OperationContract]
            double Multiply(double n1, double n2);
    
            [OperationContract]
            double Divide(double n1, double n2);
        }
    

    实现

    接口的实现没有特别的属性注释,正常实现接口即可

    
        public class CalculatorService : ICalculator
        {
            public double Add(double n1, double n2)
            {
                double result = n1 + n2;
                Console.WriteLine("Received Add({0},{1})", n1, n2);
                // Code added to write output to the console window.
                Console.WriteLine("Return: {0}", result);
                return result;
            }
    
            public double Subtract(double n1, double n2)
            {
                double result = n1 - n2;
                Console.WriteLine("Received Subtract({0},{1})", n1, n2);
                Console.WriteLine("Return: {0}", result);
                return result;
            }
    
            public double Multiply(double n1, double n2)
            {
                double result = n1 * n2;
                Console.WriteLine("Received Multiply({0},{1})", n1, n2);
                Console.WriteLine("Return: {0}", result);
                return result;
            }
    
            public double Divide(double n1, double n2)
            {
                double result = n1 / n2;
                Console.WriteLine("Received Divide({0},{1})", n1, n2);
                Console.WriteLine("Return: {0}", result);
                return result;
            }
        }
    

    配置

    对应的wcf在配置文件app.config中的配置。

    这里指定了上面提到的ABC,不过在容器中,同样也需要进行相同的配置。

    <system.serviceModel>
        <services>
          <service name="GettingStartedLib.CalculatorService">
            <host>
              <baseAddresses>
                <add baseAddress = "http://localhost:18000/GettingStarted/CalculatorService" />
              </baseAddresses>
            </host>
            <endpoint address="" binding="wsHttpBinding" contract="GettingStartedLib.ICalculator">
              <identity>
                <dns value="localhost" />
              </identity>
            </endpoint>
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
          </service>
        </services>
        <behaviors>
          <serviceBehaviors>
            <behavior>
              <serviceMetadata httpGetEnabled="True" httpsGetEnabled="True" />
              <serviceDebug includeExceptionDetailInFaults="False" />
            </behavior>
          </serviceBehaviors>
        </behaviors>
      </system.serviceModel>
    

    宿主

    宿主
    Web应用或者Console应用都可以作为宿主,这里以控制台应用为例。

    
            private static void Main(string[] args)
            { // Step 1 Create a URI to serve as the base address.
                Uri baseAddress = new Uri("http://localhost:60002/GettingStarted/");
    
                // Step 2 Create a ServiceHost instance
                ServiceHost selfHost = new ServiceHost(typeof(CalculatorService), baseAddress);
    
                try
                {
                    // Step 3 Add a service endpoint.
                    selfHost.AddServiceEndpoint(typeof(ICalculator), new WSHttpBinding(), "CalculatorService");
    
                    // Step 4 Enable metadata exchange.
                    ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
                    smb.HttpGetEnabled = true;
                    selfHost.Description.Behaviors.Add(smb);
    
                    // Step 5 Start the service.
                    selfHost.Open();
                    Console.WriteLine("The service is ready.");
                    Console.WriteLine("Press <ENTER> to terminate service.");
                    Console.WriteLine();
                    Console.ReadLine();
    
                    // Close the ServiceHostBase to shutdown the service.
                    selfHost.Close();
                }
                catch (CommunicationException ce)
                {
                    Console.WriteLine("An exception occurred: {0}", ce.Message);
                    selfHost.Abort();
                }
            }
    
    1. 创建一个Uri,这个地址就是这个服务的基础地址
    2. 创建一个SelfHost,绑定到该地址上,则该服务在该地址上运行
    3. 创建一个endpointendpoint是服务的触点,个人把他理解为例如网站中网页的地址,真正用于交互的是endpointendpoint指明了该服务提供的具体服务类型ICalculator(从而了解该服务包含哪些方法),服务的通信协议、又叫binding,服务的访问地址CalculatorService,该地址叠加在基地址Uri上。
    4. 增加behaviourbehaviour定义了服务提供的一些功能,再实例中提使能了metatdata的获取
    5. 启动宿主机

    启动后,就能在指定地址http://localhost:60002/GettingStarted/该服务了。
    不过为了通过程序访问,还需要搭建客户端

    客户端

    WCCF的客户端搭建,依赖vs自带的功能,或者使用微软的svcutil.exe工具。

    1. 新建一个console应用
    2. 增加System.ServiceModel引用
    3. 在Solution窗口中,右键点击该项目,在弹出菜单中选择Add->Service Reference
    4. 在弹出窗口中的地址中,输入服务端的地址,点击Go开始解析
    5. 解析完毕,可以看到刚刚建立的CalculatorService服务endpoint,点击OK即可引入该服务
    6. 引入服务后,就可以像本地调用一样,创建该服务实力,调用服务方法了。方法内部包含了实际的远程调用过程,不过这些对调用者是透明的。
    private static void Main(string[] args)
            {
                //Step 1: Create an instance of the WCF proxy.
                CalculatorClient client = new CalculatorClient();
    
                // Step 2: Call the service operations.
                // Call the Add service operation.
                double value1 = 100.00D;
                double value2 = 15.99D;
                double result = client.Add(value1, value2);
                Console.WriteLine("Add({0},{1}) = {2}", value1, value2, result);
    
                // Call the Subtract service operation.
                value1 = 145.00D;
                value2 = 76.54D;
                result = client.Subtract(value1, value2);
                Console.WriteLine("Subtract({0},{1}) = {2}", value1, value2, result);
    
                // Call the Multiply service operation.
                value1 = 9.00D;
                value2 = 81.25D;
                result = client.Multiply(value1, value2);
                Console.WriteLine("Multiply({0},{1}) = {2}", value1, value2, result);
    
                // Call the Divide service operation.
                value1 = 22.00D;
                value2 = 7.00D;
                result = client.Divide(value1, value2);
                Console.WriteLine("Divide({0},{1}) = {2}", value1, value2, result);
    
                //Step 3: Closing the client gracefully closes the connection and cleans up resources.
                client.Close();
    
                Console.ReadLine();
            }
    

    总结

    简单的使用WCF与web service类似,但是WCF包含了很多高级功能,如异步、跨平台、多种通信方式、安全认证等等,这些是WCF强大的地方。

  • 相关阅读:
    jvM垃圾回收
    Java快速失败和安全失败
    方法覆盖和方法重载
    leetcode-Reverse Words in a String
    自己玩玩
    leetcode-Reverse Vowels of a String
    leetcode-Reverse String
    leetcode-Multiply Strings
    java多线程-cas及atomic
    @media响应式布局
  • 原文地址:https://www.cnblogs.com/mosakashaka/p/12608231.html
Copyright © 2011-2022 走看看