zoukankan      html  css  js  c++  java
  • WCF学习

    相关链接

    http://www.cnblogs.com/iamlilinfeng/p/4083827.html

    http://www.cnblogs.com/iamlilinfeng/archive/2012/10/01/2706353.html

    1、项目目录

    主目录

    服务库目录

     

    三种宿主目录

    两种客户端访问方式

    代码见StudyNoteOfCsharp项目。

    2、WCF开发步骤

    2.1、定义和现实服务协定,在WcfServiceLibrary1服务库项目里

     

    namespace WcfServiceLibrary1
    {
        // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文件中的接口名“IService1”。
        [ServiceContract]
        public interface IService1
        {
            [OperationContract]
            int Add(int a, int b);
            [OperationContract]
            int Multiply(int a, int b);
        }
    
    }
    View Code
    namespace WcfServiceLibrary1
    {
        // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文件中的类名“Service1”。
        public class Service1 : IService1
        {
            int IService1.Add(int a, int b)
            {
                return a + b;
            }
            
            int IService1.Multiply(int a, int b)
            {
                return a * b;
            }
        }
    }
    View Code
    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
    
      <appSettings>
        <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
      </appSettings>
      <system.web>
        <compilation debug="true" />
      </system.web>
      <!-- 部署服务库项目时,必须将配置文件的内容添加到 
      主机的 app.config 文件中。System.Configuration 不支持库的配置文件。-->
      <system.serviceModel>
        <services>
          <service name="WcfServiceLibrary1.Service1">
            <host>
              <baseAddresses>
                <add baseAddress = "http://localhost:8733/Design_Time_Addresses/WcfServiceLibrary1/Service1/" />
              </baseAddresses>
            </host>
            <!-- Service Endpoints -->
            <!-- 除非完全限定,否则地址将与上面提供的基址相关 -->
            <endpoint address="" binding="basicHttpBinding" contract="WcfServiceLibrary1.IService1">
              <!-- 
                  部署时,应删除或替换下列标识元素,以反映
                 用来运行所部署服务的标识。删除之后,WCF 将
                  自动推断相应标识。
              -->
              <identity>
                <dns value="localhost"/>
              </identity>
            </endpoint>
            <!-- Metadata Endpoints -->
            <!-- 元数据交换终结点供相应的服务用于向客户端做自我介绍。 --> 
            <!-- 此终结点不使用安全绑定,应在部署前确保其安全或将其删除-->
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
          </service>
        </services>
        <behaviors>
          <serviceBehaviors>
            <behavior>
              <!-- 为避免泄漏元数据信息,
              请在部署前将以下值设置为 false -->
              <serviceMetadata httpGetEnabled="True" httpsGetEnabled="True"/>
              <!-- 要接收故障异常详细信息以进行调试,
              请将以下值设置为 true。在部署前设置为 false 
                以避免泄漏异常信息-->
              <serviceDebug includeExceptionDetailInFaults="False" />
            </behavior>
          </serviceBehaviors>
        </behaviors>
      </system.serviceModel>
    
    </configuration>
    View Code

    此项目里调用wcf服务没有用到上面app.config里的配置,所以用处不大

    2.2、将wcf服务寄宿到winform程序、console控制台程序、或是web程序里

           寄宿到winform程序里

           winform项目app.config

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
        <startup> 
            <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
        </startup>
      <!--下面是加上去的-->
      <system.serviceModel>
        <services>
          <service name="WcfServiceLibrary1.Service1">
            <host>
              <baseAddresses>
                <add baseAddress="http://localhost:8081/Service1"/>
              </baseAddresses>
            </host>
            <endpoint address="" binding="wsHttpBinding" contract="WcfServiceLibrary1.IService1"></endpoint>
          </service>
        </services>
        <behaviors>
          <serviceBehaviors>
            <behavior>
              <serviceMetadata httpGetEnabled="True"/>
              <serviceDebug includeExceptionDetailInFaults="False"/>
            </behavior>
          </serviceBehaviors>
        </behaviors>
      </system.serviceModel>
    </configuration>
    View Code

    winform界面

    代码如下

    namespace WcfServiceWinformHost
    {
        public partial class Form1 : Form
        {
            //host的地址和service在app.config里设置了
            ServiceHost host = new ServiceHost(typeof(WcfServiceLibrary1.Service1));
            public Form1()
            {
                InitializeComponent();
                
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                this.Text = "wcf服务监听已经开启";            
                host.Open();
    
            }
    
            private void button2_Click(object sender, EventArgs e)
            {
                host.Close();
                this.Text = "wcf服务监听已经停止";
            }
        }
    }
    View Code

    但“开始监听”时,在浏览器里输入http://localhost:8081/Service1会看到wcf服务已经启动,客户端程序引用http://localhost:8081/Service1地址的服务就可以。

      寄宿到console控制台

    app.config配置如下,但配置是无效的,在Program.cs程序里没有用app.config里的配置

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
        <startup> 
            <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
        </startup>
        <system.serviceModel>
            <bindings>
                <wsHttpBinding>
                    <binding name="WSHttpBinding_IService1" />
                </wsHttpBinding>
            </bindings>
            <client>
                <endpoint address="http://localhost:8081/Service1" binding="wsHttpBinding"
                    bindingConfiguration="WSHttpBinding_IService1" contract="ServiceWinformReference1.IService1"
                    name="WSHttpBinding_IService1">
                    <identity>
                        <userPrincipalName value="SHENGYUAdministrator" />
                    </identity>
                </endpoint>
            </client>
        </system.serviceModel>
    </configuration>
    View Code

     主程序代码如下:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.ServiceModel;
    using System.ServiceModel.Description;
    using WcfServiceLibrary1;
    
    namespace ConsoleApplication1
    {
        class Program
        {
            static void Main(string[] args)
            {
                // Step 1 Create a URI to serve as the base address.
                Uri baseAddress = new Uri("http://localhost:8733/WcfServiceLibrary1/Service1/");
    
                // Step 2 Create a ServiceHost instance
                ServiceHost selfHost = new ServiceHost(typeof(Service1), baseAddress);
    
                try
                {
                    // Step 3 Add a service endpoint.
                    selfHost.AddServiceEndpoint(typeof(IService1), new WSHttpBinding(), "Service1");
    
                    // 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();
                }
    
    
            }
        }
    }
    View Code

    可以看到,宿主程序将wcf服务发布到了http://localhost:8733/WcfServiceLibrary1/Service1/而不是app.config里的http://localhost:8081/Service1,客户端程序要引用 http://localhost:8733/WcfServiceLibrary1/Service1/就能访问服务

     寄宿到web网站上,wcf将寄宿到iis上

    此时服务可以写在wcf服务应用程序里

     web.config配置如下

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
    
      <appSettings>
        <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
      </appSettings>
      <system.web>
        <compilation debug="true" targetFramework="4.5" />
        <httpRuntime targetFramework="4.5"/>
      </system.web>
      <system.serviceModel>
        <behaviors>
          <serviceBehaviors>
            <behavior>
              <!-- 为避免泄漏元数据信息,请在部署前将以下值设置为 false -->
              <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
              <!-- 要接收故障异常详细信息以进行调试,请将以下值设置为 true。在部署前设置为 false 以避免泄漏异常信息 -->
              <serviceDebug includeExceptionDetailInFaults="false"/>
            </behavior>
          </serviceBehaviors>
        </behaviors>
        <protocolMapping>
            <add binding="basicHttpsBinding" scheme="https" />
        </protocolMapping>    
        <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
      </system.serviceModel>
      <system.webServer>
        <modules runAllManagedModulesForAllRequests="true"/>
        <!--
            若要在调试过程中浏览 Web 应用程序根目录,请将下面的值设置为 True。
            在部署之前将该值设置为 False 可避免泄露 Web 应用程序文件夹信息。
          -->
        <directoryBrowse enabled="true"/>
      </system.webServer>
    
    </configuration>
    View Code

    定义和现实服务协定

    namespace WcfServiceWebHost
    {
        // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文件中的接口名“IService1”。
        [ServiceContract]
        public interface IService1
        {
    
            [OperationContract]
            int Subtract(int a, int b);
        }    
    }
    View Code
    namespace WcfServiceWebHost
    {
        // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码、svc 和配置文件中的类名“Service1”。
        // 注意: 为了启动 WCF 测试客户端以测试此服务,请在解决方案资源管理器中选择 Service1.svc 或 Service1.svc.cs,然后开始调试。
        public class Service1 : IService1
        {
            public int Subtract(int a, int b)
            {
                return a - b;
            }
        }
    }
    View Code

    web运行后的地址为:http://localhost:7234/Service1.svc,在客户端调用时只要引用此地址上的服务就可

    3、客户端调用

         console控制台客户端调用console控制台服务宿主程序里的wcf服务

       在console控制台客户端引用服务,服务地址是http://localhost:8733/WcfServiceLibrary1/Service1/

       console控制台客户端程序代码如下:

    namespace WcfServiceConsoleClient
    {
        class Program
        {
            static void Main(string[] args)
            {   
               ServiceWcfServiceConsoleHostReference1.Service1Client client = new ServiceWcfServiceConsoleHostReference1.Service1Client();
               do
               {
                   var a = int.Parse(Console.ReadLine());
                   var b = int.Parse(Console.ReadLine());
                   var result = client.Multiply(a, b);
                   Console.WriteLine("Multiply({0},{1}) = {2}", a, b, result);
               } while (Console.ReadLine() != "exit");
              client.Close();
            }
        }
    }
    View Code

    运行console控制台宿主程序WcfServiceConsoleHost.exe

    运行console控制台客户端程序WcfServiceConsoleClient.exe

         console控制台客户端调用winform服务宿主程序里的wcf服务

       在console控制台客户端引用服务,服务地址是http://localhost:8081/Service1,即winform宿主程序app.config里配置的地址(其实地址也可以像上面console控制台宿主上样写在程序里而不写在app.config里)

    console控制台客户端代码如下:

    namespace WcfServiceConsoleClient
    {
        class Program
        {
            static void Main(string[] args)
            {
                ServiceWcfServiceWinformHostReference1.Service1Client client = new ServiceWcfServiceWinformHostReference1.Service1Client();
               do
               {
                   var a = int.Parse(Console.ReadLine());
                   var b = int.Parse(Console.ReadLine());
                   var result = client.Add(a, b);
                   Console.WriteLine("Add({0},{1}) = {2}", a, b, result);
               } while (Console.ReadLine() != "exit");
              client.Close();
            }
        }
    }
    View Code

    运行winform宿主程序,启动服务

    运行console控制台客户端程序WcfServiceConsoleClient.exe

         console控制台客户端调用web服务宿主程序里的wcf服务


    在console控制台上引用web服务宿主端http://localhost:7234/Service1.svc的服务

    确保web端开启

    console控制台客户端代码如下:

    namespace WcfServiceConsoleClient
    {
        class Program
        {
            static void Main(string[] args)
            {
                ServiceWcfServiceWebHostReference1.Service1Client client = new ServiceWcfServiceWebHostReference1.Service1Client();
               do
               {
                   var a = int.Parse(Console.ReadLine());
                   var b = int.Parse(Console.ReadLine());
                   var result = client.Subtract(a, b);
                   Console.WriteLine("Subtract({0},{1}) = {2}", a, b, result);
               } while (Console.ReadLine() != "exit");
              client.Close();
            }
        }
    }
    View Code

    运行console控制台客户端程序WcfServiceConsoleClient.exe

    winform客户端调用winform服务端的wcf服务

    winform客户端代码和界面如下

    namespace WcfServiceWinformClient
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                //ServiceWinformHostReference1引用的是WcfServiceWinformHost项目里app.config里baseAddress的地址
                ServiceWinformHostReference1.Service1Client client = new ServiceWinformHostReference1.Service1Client();
                textBox3.Text=client.Add(int.Parse(textBox1.Text), int.Parse(textBox2.Text)).ToString();
            }
    
            private void button2_Click(object sender, EventArgs e)
            {
                ServiceWinformHostReference1.Service1Client client = new ServiceWinformHostReference1.Service1Client();
                textBox3.Text = client.Multiply(int.Parse(textBox1.Text), int.Parse(textBox2.Text)).ToString();
            }
        }
    }
    View Code

    运行客户端,调用wcf的加法和乘法方法界面如下

    总结:wcf步骤为

    1、写服务接口和实现服务

    2、写宿主程序,可以是console控制台、winform、web等等应用程序,并调用服务类,配置好wcf,可以用app.config或是web.config来配置,也可以写在程序里,记录好配置后的服务url地址

    3、启用宿主程序,在浏览器上确保服务url地址能访问

    4、写客户端程序,程序引用宿主的服务url地址,调用服务里的方法

    宿主程序在配置wcf时,可能用以下的代码方式

                Uri baseAddress = new Uri("http://localhost:8733/WcfServiceLibrary1/Service1/");
    
                // Step 2 Create a ServiceHost instance
                ServiceHost selfHost = new ServiceHost(typeof(Service1), baseAddress);
    View Code

     baseAddress用来设置服务的地址,ServiceHost类将地址和服务类关联起来

    也可以用config配置文件来配置

    <system.serviceModel>
        <services>
          <service name="WcfServiceLibrary1.Service1">
            <host>
              <baseAddresses>
                <add baseAddress="http://localhost:8081/Service1"/>
              </baseAddresses>
            </host>
            <endpoint address="" binding="wsHttpBinding" contract="WcfServiceLibrary1.IService1"></endpoint>
          </service>
        </services>
        <behaviors>
          <serviceBehaviors>
            <behavior>
              <serviceMetadata httpGetEnabled="True"/>
              <serviceDebug includeExceptionDetailInFaults="False"/>
            </behavior>
          </serviceBehaviors>
        </behaviors>
      </system.serviceModel>
    View Code

    然后在程序里直接调用:

    //host的地址和service在app.config里设置了
            ServiceHost host = new ServiceHost(typeof(WcfServiceLibrary1.Service1));
    View Code

     认识wcf中的“ABC",A指address,就是配置文件里baseaddress的地址,说明去哪里访问服务,B指binding,说明能用什么方式去访问,如wsHttpBinding,C指Contract描述了Service能提供的各种服务。Contract有四种,包括Service Contract, Data Contract, Fault Contract和Message Contract

  • 相关阅读:
    LC 357. Count Numbers with Unique Digits
    LC 851. Loud and Rich
    LC 650. 2 Keys Keyboard
    LC 553. Optimal Division
    LC 672. Bulb Switcher II
    LC 413. Arithmetic Slices
    LC 648. Replace Words
    LC 959. Regions Cut By Slashes
    Spring框架学习之注解配置与AOP思想
    Spring框架学习之高级依赖关系配置(二)
  • 原文地址:https://www.cnblogs.com/shengyu-kmust/p/4201142.html
Copyright © 2011-2022 走看看