(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(); }
结果