以前在企业用的服务端是wcf写的,可是尚未深刻钻研,近期找工作,面试的时候好多少人探望这些总提问,那里做个复习

就用微软官方上的例子,搭一个归纳的wcf服务,分6步

一定义服务协定也正是契约,其实正是概念三个服务接口,这个人前面是精晓客户端用的,然后也报告前面承载程序应该什么加载服务

   主要涉嫌二日性子:二个是瑟维斯Contract(接口的本性,定义那个是劳动契约,里边又有的安装参数能够安装一下),OperationContract设置接口的章程的,如果不设置,方法就不会呗公开

  那里是平昔新建的wcf的服务程序,vs自动给生成了一个接口,就平素在那么些里面添加了多少个总括的接口函数了

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;

namespace GettingStartedLib
{

    // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文件中的接口名“IService1”。
    //协定
    [ServiceContract(//CallbackContract =typeof(ICallBack),//双工时的返回协定
        ConfigurationName = "Calculator",//配置文件重的服务名
        Name = "ICalculator",//webservice描述文件重的portType名
        Namespace ="http://SampleWcfTest",//webservice描述文件重的portType命名空间
        ProtectionLevel =System.Net.Security.ProtectionLevel.EncryptAndSign,//保护等级
        SessionMode =SessionMode.Allowed)]//设置会话的支持模式
    public interface ICalculator
    {

        [OperationContract]
        string GetData(int value);

        [OperationContract]
        CompositeType GetDataUsingDataContract(CompositeType composite);
        //定义方法的操作,带了该特性才会被公布
        [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);

        // TODO: 在此添加您的服务操作
    }
    public interface ICallBack
    {
        [OperationContract(IsOneWay = true)]
        void Reply(string responseToGreeting);
    }

    // 使用下面示例中说明的数据约定将复合类型添加到服务操作。
    [DataContract]
    public class CompositeType
    {
        bool boolValue = true;
        string stringValue = "Hello ";

        [DataMember]
        public bool BoolValue
        {
            get { return boolValue; }
            set { boolValue = value; }
        }

        [DataMember]
        public string StringValue
        {
            get { return stringValue; }
            set { stringValue = value; }
        }
    }
}

二完成下边包车型客车接口,vs自动生成了svc文件和对应的svc.cs文件,间接双击就是呼应的完结类了,吧接口实现就好了,那个svc文件右键用文件编辑器打开方可展开编写制定,假设前边用IIS加载的时候要求修改里边的事物

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;

namespace GettingStartedLib
{
    // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码、svc 和配置文件中的类名“Service1”。
    // 注意: 为了启动 WCF 测试客户端以测试此服务,请在解决方案资源管理器中选择 Service1.svc 或 Service1.svc.cs,然后开始调试。
    public class Calculator : ICalculator
    {
        public string GetData(int value)
        {
            return string.Format("You entered: {0}", value);
        }

        public CompositeType GetDataUsingDataContract(CompositeType composite)
        {
            if (composite == null)
            {
                throw new ArgumentNullException("composite");
            }
            if (composite.BoolValue)
            {
                composite.StringValue += "Suffix";
            }
            return composite;
        }
        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;
        }
    }
}

三 承载服务,承载服务有两种方法,同时又安插到协和式飞机的绑定难题,

  绑定分类:BasicHttpBinding  最基础的http绑定,
        NetTcpbingding  TCP的  

        NetNamePipeBinding  IPC,也正是经过间通讯,没用过。。

        WSHttpBinding  这么些是破例的http/Https协议 加了此外东西的

        NetMsmqBindiing,那几个是音讯队列,笔者没用过,那东西好像须要额外装微软的信息队列才能够用

  那里笔者中央就用wshttpbinding来贯彻,

  承载方式:壹)用控制台程序,直接用servicehost来承载服务,自个儿组织终结点:

            //服务的地址
            Uri baseAddress = new Uri("http://localhost:8000/GettingStarted/");
            //承载服务的宿主
            ServiceHost selfHost = new ServiceHost(typeof(Calculator), baseAddress);

            try
            {
                selfHost.AddServiceEndpoint(typeof(ICalculator), new WSHttpBinding(), "Calculator");
                ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
                smb.HttpGetEnabled = true;
                selfHost.Description.Behaviors.Add(smb);
                selfHost.Open();
                Console.WriteLine("The service is ready.");
                Console.WriteLine("input<exit> to terminate service.");
                Console.WriteLine();
                while ("exit" == Console.ReadLine())
                {
                    selfHost.Close();
                }
            }
            catch (CommunicationException ex)
            {
                Console.WriteLine(ex.Message);
                selfHost.Abort();
                Console.ReadLine();
            }

    二) 用IIS承载,那里又几种办法,通过internet的法子
这一个能够直接在vs中调剂的,选中svc文件点调节和测试会弹出三个wcf的客户端测试程序,能够一贯开始展览测试,不过这一个客户端无法测试异步,只好测同步

    那中艺术重点是供给配备3个web.config文件,计划的话,间接在IIS添加网址服务程序,把变化的DLL和web.config放在三个目录下应当跟那几个调试是同样的(那种情势IIS5
6 只援助HTTP)

    还是能透过WAS(进度激活服务,帮忙的说道比上边多,这一个就从不深入钻研了···)

<?xml version="1.0" encoding="utf-8"?>
<configuration>

  <appSettings>
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
  </appSettings>
  <system.web>
    <compilation debug="true" targetFramework="4.5.2" />
    <httpRuntime targetFramework="4.5.2"/>
  </system.web>
  <system.serviceModel>
    <services>
      <service name="GettingStartedLib.Calculator" behaviorConfiguration="MyServiceTypeBehaviors" >
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8001/"/>
          </baseAddresses>
        </host>
        <endpoint address="CalculatorService" binding="wsHttpBinding" contract="Calculator">
        </endpoint>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="MyServiceTypeBehaviors" >
          <!-- 将下列元素添加到服务行为配置中。 -->
          <serviceMetadata httpGetEnabled="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
  <system.webServer>
    <!--<modules runAllManagedModulesForAllRequests="true"/>-->
    <!--
        若要在调试过程中浏览 Web 应用程序根目录,请将下面的值设置为 True。
        在部署之前将该值设置为 False 可避免泄露 Web 应用程序文件夹信息。
      -->
    <directoryBrowse enabled="true"/>
  </system.webServer>

</configuration>

  三)通过windows服务程序承载,那几个里面开首也是servicehost来落实,只不过是挂在windows服务程序上,需求本身完结贰个windows服务,也正是继续servicebase类,重写onstart,在onstart中用servicehost加载服务,在stop中甘休服务,同时要求安顿文件正是程序的安顿文件app.config记得生成到目录下,配置终结点。服务类生成的先后必要设置,还亟需后续install达成三个安装类,把变化的服务程序安装到windows系统服务去,然后就足以在服务中运行服务,

本条设置是在协会者权限下进入对应的.netframework目录下运行installutil
path(程序目录) 那里用的是4.五 ,正是v4.0。。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using GettingStartedLib;
using System.ServiceModel.Description;
using System.ServiceModel;
using System.ServiceProcess;
using System.Configuration.Install;
using System.ComponentModel;

namespace WcfConsole
{
    public class serviceCalss : ServiceBase
    {
        public ServiceHost serviceHost = null;
        public serviceCalss()
        {
            ServiceName = "WCFWindowsServiceSample";

        }
        protected override void OnStart(string[] args)
        {
            if (serviceHost != null)
            {
                serviceHost.Close();
            }
            serviceHost = new ServiceHost(typeof(Calculator));

            serviceHost.Open();
        }

        protected override void OnStop()
        {
            if (serviceHost != null)
            {
                serviceHost.Close();
                serviceHost = null;
            }
        }
    }
    class Program
    {
        static void Main(string[] args)
        {

            ServiceBase.Run(new serviceCalss());

            //服务的地址
            Uri baseAddress = new Uri("http://localhost:8000/GettingStarted/");
            //承载服务的宿主
            ServiceHost selfHost = new ServiceHost(typeof(Calculator), baseAddress);

            //try
            //{
            //    selfHost.AddServiceEndpoint(typeof(ICalculator), new WSHttpBinding(), "Calculator");
            //    ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
            //    smb.HttpGetEnabled = true;
            //    selfHost.Description.Behaviors.Add(smb);
            //    selfHost.Open();
            //    Console.WriteLine("The service is ready.");
            //    Console.WriteLine("input<exit> to terminate service.");
            //    Console.WriteLine();
            //    while ("exit" == Console.ReadLine())
            //    {
            //        selfHost.Close();
            //    }
            //}
            //catch (CommunicationException ex)
            //{
            //    Console.WriteLine(ex.Message);
            //    selfHost.Abort();
            //    Console.ReadLine();
            //}
        }
    }

    [RunInstaller(true)]
    public class ProjectInstaller : Installer
    {
        private ServiceProcessInstaller process;
        private ServiceInstaller service;

        public ProjectInstaller()
        {
            process = new ServiceProcessInstaller();
            process.Account = ServiceAccount.LocalSystem;
            service = new ServiceInstaller();
            service.ServiceName = "WCFWindowsServiceSample";
            Installers.Add(process);
            Installers.Add(service);
        }
    }
}

相应的陈设文件

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
    </startup>
  <system.serviceModel>
    <services>
      <!-- This section is optional with the new configuration model
           introduced in .NET Framework 4. -->
      <service name="GettingStartedLib.Calculator"
               behaviorConfiguration="CalculatorServiceBehavior">
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8000/"/>
          </baseAddresses>
        </host>
        <endpoint address=""
                  binding="wsHttpBinding"
                  contract="Calculator" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="CalculatorServiceBehavior">
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="False"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>

四 服务端承载好了,就足以用客户端调用服务了,又三种情势

  客户端间接引用已经运营的劳务,vs会自动生成3个相应的client类,里边又设置好的劳动路径和接口之类的,也得以团结内定路线,只用他的函数,记得close

           // CalculatorClient client = new CalculatorClient();
            var client = myChannelFactory.CreateChannel();


            double value1 = 100.00D;
            double value2 = 15.99D;
            double result = client.Add(value1, value2);
            Console.WriteLine("Add({0},{1}) = {2}", value1, value2, result);

  也足以用ChannelFactory<TChannel>类来布局多个client,那种情势是引用服务的契约接口,

     var myBinding = new WSHttpBinding();
            EndpointAddress myEndpoint = new EndpointAddress("http://localhost:8000/GettingStarted/");
            //EndpointAddress myEndpoint = new EndpointAddress("http://localhost:8000/"); 
            ChannelFactory<ICalculator> myChannelFactory = new ChannelFactory<ICalculator>(myBinding, myEndpoint);

  那里边都足以用配备文件来安装终结点,约等于绑定类型和地方,配置方式与服务端类似

5,六就是安排和调用,那里就背着了

那里只是简短的wcf实例,

实质上还有内容从未关系:

一不一致的绑定类型,怎么采取,网上有个图是判定哪些情状选取相应的绑定类型,其实正是采纳情商

二加密,因为里面包车型地铁主次用的是basichttpbingding便是就是大旨的http绑定,客户端没用引用服务端,服务端以web服务的情势公开服务,客户端直接以http请求的款式来与服务端通讯,那样客户端cs和bs能够公用多少个服务端,不过尚未加密,传输的始末是完全公之于世的··讲道理web服务这东西本来正是发过去给人看的·公开应该也没啥好像····,面试的时候问到这几个难题直接懵逼了···那里权且没写
··那玩意好像挺费劲的···

3那里在4.5的条件下编写制定的,服务公开以后会自动生成对应的异步执行方式,与前面的不2秘诀区别,从前是老式的beginxxx的异步情势,再次回到三个Iasyncresult的结果,那里是4.伍的async/await的样式来实行异步操作

四 wcf服务是足以包容asp.net
,也得以回到json格式的对象··这些能够通过安装方法的操作性格可以设置

伍wcf服务援救双工,那一个就很流弊了,不过讲道理tcp那种自小编就帮助双工,没实际钻探

陆在双工形式下帮助回调,那么些意思好像是客户端请求实现再启程二个回调服务么···
没钻探···

。。。。。。

 

相关文章

网站地图xml地图