前面以商店之所以底服务端是wcf写的,但是没有尖锐钻研,最近摸索工作,面试的早晚多人数目此总问,这里做个复习

纵使用微软官方及的例子,搭一个简单易行的wcf服务,分6步

1
定义服务协定为便是契约,其实就是是概念一个劳务接口,这家伙后边是开诚布公客户端用的,然后为告知后边承载程序应该什么加载服务

   主要涉及个别单特色:一个凡ServiceContract(接口的特色,定义之是劳动契约,里边又有的装置参数可以装一下),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; }
        }
    }
}

2
实现上的接口,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;
        }
    }
}

3 承载服务,承载服务来几种植艺术,同时以计划及谋的绑定问题,

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

        NetNamePipeBinding  IPC,也尽管是过程之中通信,没因此了。。

        WSHttpBinding  这个是超常规之http/Https协议 加了另外东西的

        NetMsmqBindiing,这个是信队列,我没有因此过,这玩意好像需要额外装微软的信队列才好据此

  这里自己基本就因故wshttpbinding来促成,

  承载方式:1)用控制台程序,直接用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();
            }

    2) 用IIS承载,这里以有限栽艺术,通过internet的艺术
这个可一直在vs中调剂的,选中svc文件点调试会弹出一个wcf的客户端测试程序,可以直接进行测试,但是这客户端不克测试异步,只能测同步

    这受到艺术主要是索要配置一个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>

  3)通过windows服务程序承载,这个里面开始也是servicehost来贯彻,只不过是悬挂于windows服务程序上,需要好实现一个windows服务,也就是延续servicebase类,重写onstart,在onstart中因故servicehost加载服务,在stop中已服务,同时需要配置文件就是次的布置文件app.config记得生成到目下,配置了点。服务类生成的次需要设置,还需连续install实现一个设置类,把变化的服务程序安装到windows系统服务去,然后就是可在服务着启动服务,

这个装置是以组织者权限下上对应的.netframework目录下运行installutil
path(程序目录) 这里用的凡4.5 ,就是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>

4 服务端承载好了,就好为此客户端调用劳动了,又简单种植方式

  客户端直接引用已经运行的劳动,vs会自动生成一个遥相呼应之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,6虽是部署以及调用,这里就是隐瞒了

这边只是简短的wcf实例,

骨子里还有内容尚未干:

1
不同之绑定类型,怎么取舍,网上发出只图是判断什么状态择相应之绑定类型,其实就是选取情商

2
加密,因为中的先后用的是basichttpbingding就是就是是基本的http绑定,客户端没因此引用服务端,服务端以web服务的款型公开服务,客户端直接盖http请求的样式来跟服务端通信,这样客户端cs和bs可以公用一个服务端,但是从未加密,传输的情是截然公之于世之··讲道理web服务及时东西本来就是是犯过去叫丁看之·公开应也未曾啥好像····,面试的早晚问到是题材一直懵逼了···这里暂时并未写
··这玩意好像特别烦的···

3
这里以4.5底环境下编制的,服务公开以后会自动生成对应的异步执行措施,与之前的措施各异,之前是老式的beginxxx的异步方式,返回一个Iasyncresult的结果,这里是4.5底async/await的款型来实施异步操作

4 wcf服务是足以兼容asp.net
,也可回去json格式的对象··这个可以透过安装方法的操作特性可设置

5
wcf服务支持双工,这个就算那个流弊了,不过讲道理tcp这种自己就支持双工,没具体研究

6
在双工模式下支持回调,这个意思好像是客户端请求完成再启程一个回调服务么···
没研究···

。。。。。。

 

相关文章

网站地图xml地图