(1)WCF托管

wcf 托管方式有很多种,常见的托管方式,iis,was,控制台,winfrom等。

先创建一个wcf服务

 IService1.cs

using System.ServiceModel;
namespace WcfServiceLibrary6
{
    [ServiceContract]
    public interface IService1
    {
        [OperationContract]
        string GetData(int value);
    }
}

Service1.cs

namespace WcfServiceLibrary6
{
    public class Service1 : IService1
    {
        public string GetData(int value)
        {
            return string.Format("传入了数字: {0}", value);
        }
    }
}

 下面的的宿主都调用这个例子,如果用iis和was做宿主。app.config的配置在wcf下进行。如果

 一、单纯只用IIS做宿主

配置wcf的 App.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <!--指定 ASP.NET 4.5 中的异步代码路径的行为方式-->
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
  </appSettings>
  <system.web>
    <compilation debug="true" />
  </system.web>
  <system.serviceModel>
    <services>
      <service name="WcfServiceLibrary6.Service1">
        <!--host这段可以测试时启动wcf测试客户端,运行后除了弹出测试客户端,也可以在浏览器中用此address访问-->
        <host>
          <baseAddresses>
            <add baseAddress = "http://localhost:8733/Service1/" />
          </baseAddresses>
        </host>
        <endpoint binding="basicHttpBinding" contract="WcfServiceLibrary6.IService1" />
      </service>
    </services>
    <!--元数据-->
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="True"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>

 注意

如果像IIS这种自带地址的容器,可以既不需要基地址同时也不需要终结点地址。

  <system.serviceModel>
    <services>
      <service name="WcfServiceLibrary6.Service1">
        <endpoint binding="basicHttpBinding" contract="WcfServiceLibrary6.IService1" />
      </service>
    </services>
    <!--元数据-->
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="True"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

 如果不带基地址,在visual studio中 F5运行调试的时候就会报错无法进行调试了,但部署的iis还是可以正常使用的。

 

2.创建IIS

 3.发布

右键vs工程项目,发布后

IIS根目录下

 

bin里

 

 可能遇到的错误1

错误原因可能是应用程序池版本太低,

 

改成 framework4.0

 

可能遇到的错误2

添加MIME

.svc

application/octet-stream

可能遇到的错误3

用aspnet_regiis注册4.0框架

cd C:\Windows\Microsoft.NET\Framework\v4.0.30319

aspnet_regiis.exe -i

4.一个简单的客户端调用,之后开一篇专门介绍

创建一个客户端控制台后,添加服务引用

 

自动添加xml

    <system.serviceModel>
        <bindings>
            <basicHttpBinding>
                <binding name="BasicHttpBinding_IService1" />
            </basicHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://xtz-01805141702:8001/WcfServiceLibrary4.Service1.svc"
                binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IService1"
                contract="ServiceReference1.IService1" name="BasicHttpBinding_IService1" />
        </client>
    </system.serviceModel>

并自动导入 System.ServiceModel

编写客户端程序

using System;
namespace ConsoleApp3
{
    class Program
    {
        static void Main(string[] args)
        {
            var client = new ServiceReference1.Service1Client();
            var str=client.GetData(2);
            Console.WriteLine(str);
            Console.ReadLine();
        }
    }
}

 运行

 

二、使用Windows Process Activation Service (WAS)-Windows进程激活服务托管

1.用IIS托管的应用程序

2.添加wcf功能

控制面板-windows功能

之后会自动勾选,was

3.在IIS创建一个网站

红框是安装wcf功能后多出来的选项。

再添加一个net.tcp协议。

 

  4.开启net.tcp协议

 5.wcf配置

  <system.serviceModel>
    <services>
      <service name="WcfServiceLibrary6.Service1">
        <endpoint binding="netTcpBinding"  contract="WcfServiceLibrary6.IService1" />
        <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior >
          <serviceMetadata httpGetEnabled="false"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

 6.访问

 

如果同时开启 mex和 http-get

可以同时引用 

http://localhost:8002/WcfServiceLibrary6.Service1.svc  和

net.tcp://localhost/WcfServiceLibrary6.Service1.svc/mex     808端口是net.tcp的默认端口所以没有显示出来

 如果只开启mex ,虽然可以用http方式查看到,但只能用tcp的方式引用

错误1 

(1)cmd

(2)cd  C:/Windows/Microsoft.NET/Framework/v4.0.30319

(3)aspnet_regiis.exe -i

 

三、控制台托管

 wcf程序目录

创建一个控制台,引用上面的wcf工程和System.ServiceModel。

XML方式配置终结点

Program.cs

using System;
using System.ServiceModel;
using WcfServiceLibrary6;

namespace ConsoleApp6
{
    class Program
    {
        static void Main(string[] args)
        {
            ServiceHost host = new ServiceHost(typeof(Service1));
            host.Open();
            Console.WriteLine("Service已经启动,按任意键终止服务!");
            Console.Read();
            host.Close();
        }
    }
}

App.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6" />
  </startup>
  <system.serviceModel>
    <services>
      <service name="WcfServiceLibrary6.Service1">
        <host>
          <baseAddresses>
            <add baseAddress = "http://localhost:8733/" />
          </baseAddresses>
        </host>
        <endpoint address="" binding="basicHttpBinding" contract="WcfServiceLibrary6.IService1">
        </endpoint>
        <!--此方式叫做元数据交换终结点MEX的标准方式,如果开启了基于http-get的元数据serviceMetadata的httpGetEnabled="True",
        两种方式必须至少使用一种-->
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <!--如果开启了MEX, 就可以只写 serviceMetadata 标签-->
          <serviceMetadata httpGetEnabled="True"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>

 

 服务端编程方式配置终结点

删除 App.config<system.serviceModel></system.serviceModel> 利用服务端编程的方式托管wcf

同样引入引用上面的wcf工程dll和System.ServiceMode0.dlll。

 Program.cs

    class Program
    {
        static void Main(string[] args)
        {
            //增加两个基地址
            Uri baseAddressTcp = new Uri("net.tcp://localhost:9876/");
            Uri baseAddressHttp = new Uri("http://localhost:9879/");
            //第二个参数可以接受url类型的数组,这就有了两个基地址
            ServiceHost host = new ServiceHost(typeof(Service1),baseAddressTcp);

            //设置http-get元数据交换为
            ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
            smb.HttpGetEnabled = true;
            smb.HttpGetUrl = baseAddressHttp;
            host.Description.Behaviors.Add(smb);

            //设置终结点相当于xml的abc,第一个参数contract契约,第二个参数binding绑定,第三个参数address地址
            host.AddServiceEndpoint(typeof(IService1), new NetTcpBinding(), "");
            host.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexTcpBinding(), "mex");

            host.Open();
            Console.WriteLine("Service已经启动,按任意键终止服务!");
            Console.Read();
            host.Close();
        }
    }

正式运行时设置取消暴露的http服务接口

smb.HttpGetEnabled = false;

访问http

 

 

添加服务引用

 

四 windows服务做宿主

 1.创建windows服务

对应红箭头,右键安装服务

引用 

 wcfseviceLibrary6.dll是wcf服务。

2.设置属性

 

 3

 Service1.cs.

    public partial class Service1 : ServiceBase
    {
        public ServiceHost serviceHost;
        public Service1()
        {
            InitializeComponent();
        }

        protected override void OnStart(string[] args)
        {
            serviceHost=new ServiceHost(typeof(WcfServiceLibrary6.Service1));
            serviceHost.Open();
        }

        protected override void OnStop()
        {
            if (serviceHost != null)
            {
                serviceHost.Close();
            }
        }
    }

App.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6" />
    </startup>
  <system.serviceModel>
    <services>
      <service name="WcfServiceLibrary6.Service1">
        <host>
          <baseAddresses>
            <add baseAddress="net.tcp://localhost:8001/"/>
          </baseAddresses>
        </host>
        <endpoint address="" binding="netTcpBinding"  contract="WcfServiceLibrary6.IService1"></endpoint>
        <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior >
          <serviceMetadata httpGetEnabled="true" httpGetUrl="http://localhost:8002"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>

4.部署

参照 https://www.cnblogs.com/buchizaodian/p/6160816.html

注意 InstallUtil.exe工具要v4.0里的   在 C:\Windows\Microsoft.NET\Framework\v4.0.30319

InstallService-WcfService.cmd  安装win服务代码,

InstallUtil.exe WindowsService1.exe
pause

UninstallService-WcfService.cmd 卸载服务代码

InstallUtil.exe /u WindowsService1.exe 
pause

注意 这三个.exe工具属性设置成,始终复制。编译时就可以自动拷贝到bin文件夹下

 

 

5.

 

 

四、winform 

比如在右下角做一个图标程序,开关控制wcf运行关闭等功能。略

 

五、元数据交换

想要于客户端通讯必须开启元数据交换,开启方式有两种,基于HTTP-GET的元数据交换和元数据交换终结点。

(1)基于HTTP-GET的元数据交换

HTTP-GET的元数据交换属于一种服务行为,开启以后是这种画面。(即使非IIS容器也ok)

在xml中开启行为

    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="True"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>

 

 serviceMetadata 标签有一个 httpGetUrl属性。可以是相对地址,也可以是绝对地址。

相对地址

    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="True" httpGetUrl="GetUrlService"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>

 

绝对地址

报错???

 

用代码开启行为

 ????

(2)元数据交换终结点

http-get的方式不是行业标准的方式。标准方式是使用元数据交换终结点,他可以支持其他的平台

  <system.serviceModel>
    <services>
      <service name="WcfServiceLibrary6.Service1">
        <endpoint binding="basicHttpBinding" contract="WcfServiceLibrary6.IService1" />
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

 

五、基础

1.基地址

 

2.同一个host可以没有基地址,也可以有多个基地址。但多个基地址有要求,多个基地址不能采用相同的协议。

可以让同一个服务的多个终结点使用相同的基地址,但URL不能相同

 

2.绑定配置

3.默认绑定

4.协议映射

5.Configure()方法编程终结点配置

6.默认行为

 

7.默认终结点

如果服务只有基地址,没有终结点,则wcf会为服务默认添加终结点。

终结点的binding类型会根据基地址自动推断。

默认添加的终结点数=基地址数*契约数。

如果契约如下

IService1

    [ServiceContract]
    public interface IService1
    {
        [OperationContract]
        string GetData(int value);
    }

    [ServiceContract]
    public interface IService2
    {
        [OperationContract]
        string GetData2(int value);
    }

Service1.cs

    public class Service1 : IService1,IService2
    {
        public string GetData(int value)
        {
            return string.Format("You entered: {0}", value);
        }

        public string GetData2(int value)
        {
            return string.Format("请输入: {0}", value);
        }
    }

当服务端宿主设置了两个基地址但没有终结点

        static void Main(string[] args)
        {
            Uri httpBaseAddress = new Uri("http://localhost:9001/");
            Uri tcpBaseAddress = new Uri("net.tcp://localhost:9002/");

            ServiceHost host = new ServiceHost(typeof(Service1), httpBaseAddress, tcpBaseAddress);

            ////启动行为
            ServiceMetadataBehavior smb = host.Description.Behaviors.Find<ServiceMetadataBehavior>();
            if (smb == null)
            {
                smb = new ServiceMetadataBehavior();
            }
            smb.HttpGetEnabled = true;
            host.Description.Behaviors.Add(smb);
            host.Open();
            Console.WriteLine("Service已经启动,按任意键终止服务!");
            Console.Read();
            host.Close();
        }

结果

 

posted @ 2018-11-12 10:46  富坚老贼  阅读(347)  评论(0编辑  收藏  举报