WCF学习之三, 寄宿方式 代码,配置文件
可以通过代码或者配置文件寄宿WCF服务,在使用过程中的一些心得,记录一下,方便后续查阅。
预备知识,几个地址的作用
1、 behavior.HttpGetUrl 定义元数据的地址,如果不定义基地址,则必须定义HttpGetUrl ,是The absolute or relative location of the metadata.
2、baseAddresses 服务的地址,因为元数据(metadata)是属于一个host的,并不属于一个endpoint。此基地址就是客户端添加服务引用的地址,
所以baseAddress解决了Where to locate the WCF Service?
如果定义endpoint daaress="",则endpoint daaress就等于baseAddresses
3、终结点endpoint address ,用于和客户端通信,服务端与客户端endpoint的address必须严格对应。
4、在这三个地址中如果没有定义基地址则另外两个地址HttpGetUrl,endpoint address必须都不能为空
5、如果定义了baseaddress,则另外两个地址均可为空。此时endpoint address就是baseaddress定义的url
如服务端终结点配置为:
<endpoint address="http://127.0.0.1:8882/DBServer" binding="wsHttpBinding" contract="IContract.IContract" />
即服务端定义address为"http://127.0.0.1:8882/DBServer" ,那么客户端的终结点address也必须为"http://127.0.0.1:8882/DBServer" 才可以建立通讯。
当我们Host一个WCF Service的时候,我们必须给他定义一个或多个Endpoint,然后service通过这个定义的Endpoint进行监听来自Client端的请求。当我们的Application需要调用这个Service的时候,因为Client 和Service是通过Endpoint的进行通信的, 所以我们必须为我们的Application定义Client端的Endpoint。只有当Client的Endpoint和Service端某个Endpoint相互匹配(Service端可以为一个Service定义多个Endpoint),Client端的请求才能被Service端监听到。也就是说,我们只有在Client具有一个与Service端完全匹配的Endpoint,我们才能调用这个Service。而这种匹配是比较严格的,比如从匹配Address方面,Client端和Service端的Endpoint Address不仅仅在URI上要完全匹配Service, 他们的Headers也需要相互匹配。对于Binding, 一般地,Client需要有一个与Service端完全一样的Binding,他们之间才能通信。
4、如果定义了基地址,则endpoint address可以设为空,这样所有endpoint的address就是基地址所定义的url
以下是一个建立wcf服务及调用的例子
1、新建一个控制台项目,添加以下程序集引用
using System.ServiceModel;
using System.ServiceModel.Web;
2、添加类IContract,只是为了演示,Contract和Service都建在一个项目里面了
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Web; namespace IContract //注意:如果命名空间为WCFHost,则在采用配置文件寄宿服务的时候会不认配置文件,不知道为什么
{
[ServiceContract]
public interface IContract
{
[OperationContract]
[WebInvoke(UriTemplate = "Add/{x}/{y}")]
double Add(double x, double y); } }
3、添加类DBService
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace DBService //注意:如果命名空间为WCFHost,则在采用配置文件寄宿服务的时候会不认配置文件,不知道为什么
{
public class DBService:IContract.IContract
{
public double Add(double x, double y)
{
return x+y;
}
}
}
4、使用代码方式配置服务并开启服务,三个地址都进行了定义
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Web; namespace WCFHost
{
class Program
{
static void Main(string[] args)
{
try
{
//Uri uri = new Uri("http://127.0.0.1:8881/DBServer"); //和下面一句等价
Uri uri = new Uri("http://localhost:8881/DBServer"); using (ServiceHost host = new ServiceHost(typeof(DBService.DBService), uri))
{
//定义元数据发布方式,此处 通过在服务所在的URL后加“?wsdl”的方式公布WSDL,可直接通过HTTP访问得到。
System.ServiceModel.Description.ServiceMetadataBehavior behavior = new System.ServiceModel.Description.ServiceMetadataBehavior();
behavior.HttpGetEnabled = true;
//此句也可不要,HttpGetUrl定义元数据的url
behavior.HttpGetUrl = new Uri("http://localhost:8882/DBService");
host.Description.Behaviors.Add(behavior); Uri endpointAddress =new Uri("http://127.0.0.1:8883/DBServer"); //添加终结点
host.AddServiceEndpoint(typeof(IContract.IContract), new WSHttpBinding(), endpointAddress); ////定义终结点地址(如果定义了baseadress,终结点地址也可为空)
//host.AddServiceEndpoint(typeof(IContract.IContract), new WSHttpBinding(), ""); host.Opened += host_Opened;
host.Open();
Console.ReadLine();
}
}
catch (Exception e)
{
throw e;
}
} static void host_Opened(object sender, EventArgs e)
{
Console.WriteLine("DBService opened successful");
}
}
}
5、使用配置文件配置服务并开启服务,作用同4
5.1 添加配置文件,配置文件中定义了三个address,基地址(服务地址),元数据地址、与客户端的通讯地址
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="metadataBehavior">
<serviceMetadata httpGetEnabled="true" httpGetUrl="http://127.0.0.1:8881/DBServer"></serviceMetadata>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<!--注意此处name必须与第三步服务的命名空间一致-->
<service behaviorConfiguration="metadataBehavior" name="DBService.DBService">
<endpoint address="http://127.0.0.1:8882/DBServer" binding="wsHttpBinding" contract="IContract.IContract" />
<host>
<baseAddresses>
<add baseAddress="http://127.0.0.1:8883/DBServer"/>
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
</configuration>
5.2 开启服务
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Web; namespace WCFHost
{
class Program
{
static void Main(string[] args)
{
try
{
ServiceHost host1 = new ServiceHost(typeof(DBService.DBService));
host1.Opened += host_Opened;
host1.Open();
Console.ReadLine();
}
catch (Exception e)
{
throw e;
}
} static void host_Opened(object sender, EventArgs e)
{
Console.WriteLine("DBService opened successful");
}
}
}
6、在浏览器中打开服务地址:http://127.0.0.1:8883/DBServer,如下图
打开元数据地址:http://127.0.0.1:8881/DBServer,如下图
客户端添加服务,使用服务地址或者元数据地址均可找到服务。
而终结点地址:http://127.0.0.1:8882/DBServer,无法打开,
7、在客户端调用服务时,定义终结点address必须服务定义的终结点address匹配,如下
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Web; namespace WCFClient
{
class Program
{
static void Main(string[] args)
{
WSHttpBinding binding = new WSHttpBinding();
EndpointAddress address = new EndpointAddress(new Uri("http://127.0.0.1:8882/DBServer"));
ServiceReference1.ContractClient client = new ServiceReference1.ContractClient(binding, address);
double i = client.Add(1, 2);
Console.WriteLine(i);
Console.ReadLine();
}
}
}
8、只定义baseAddress,不定义其他两个address
8.1 配置文件定义
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="metadataBehavior">
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<!--注意此处name必须与第三步服务的命名空间一致-->
<service behaviorConfiguration="metadataBehavior" name="DBService.DBService">
<endpoint address="" binding="wsHttpBinding" contract="IContract.IContract" />
<host>
<baseAddresses>
<add baseAddress="http://127.0.0.1:8883/DBServer"/>
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
</configuration>
开启服务
ServiceHost host1 = new ServiceHost(typeof(DBService.DBService));
host1.Opened += host_Opened;
host1.Open();
Console.ReadLine();
8.2 代码定义并开启服务
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Web; namespace WCFHost
{
class Program
{
static void Main(string[] args)
{
try
{
//Uri uri = new Uri("http://127.0.0.1:8881/DBServer"); //和下面一句等价
Uri uri = new Uri("http://localhost:8881/DBServer"); using (ServiceHost host = new ServiceHost(typeof(DBService.DBService), uri))
{
//定义元数据发布方式,此处 通过在服务所在的URL后加“?wsdl”的方式公布WSDL,可直接通过HTTP访问得到。
System.ServiceModel.Description.ServiceMetadataBehavior behavior = new System.ServiceModel.Description.ServiceMetadataBehavior();
behavior.HttpGetEnabled = true;
host.Description.Behaviors.Add(behavior); host.AddServiceEndpoint(typeof(IContract.IContract), new WSHttpBinding(), ""); host.Opened += host_Opened;
host.Open();
Console.ReadLine();
}
}
catch (Exception e)
{
throw e;
}
} static void host_Opened(object sender, EventArgs e)
{
Console.WriteLine("DBService opened successful");
}
}
}
8.3 客户端,直接添加服务引用会自动生成配置文件,然后调用
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IContract" />
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:8881/DBServer" binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_IContract" contract="ServiceReference1.IContract"
name="WSHttpBinding_IContract" />
</client>
</system.serviceModel>
</configuration>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Web; namespace WCFClient
{
class Program
{
static void Main(string[] args)
{
ServiceReference1.ContractClient client = new ServiceReference1.ContractClient(); double i = client.Add(1, 2);
Console.WriteLine(i);
Console.ReadLine(); }
}
}
8.4 也可不用配置文件,通过代码直接调用
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Web; namespace WCFClient
{
class Program
{
static void Main(string[] args)
{ WSHttpBinding binding = new WSHttpBinding();
EndpointAddress address = new EndpointAddress(new Uri("http://127.0.0.1:8881/DBServer"));
ServiceReference1.ContractClient client = new ServiceReference1.ContractClient(binding, address);
client.Endpoint.Binding = binding; double i = client.Add(1, 2);
Console.WriteLine(i);
Console.ReadLine(); }
}
}
9、比较WCF发布元数据的两种方式,不管哪种方式ServiceMetadata节点必须存在。
元数据描述服务的细节,导出以及发布元数据,都是由一个服务中的ServiceMetadataBehavior实现的。
必须为服务配置ServiceMetadata行为,即配置节点,才能为发布元数据,才能再使用httpGetEnabled=true或者httpGetEnabled=false发布元数据。
<serviceBehaviors>
<behavior name="metadataBehavior">
<serviceMetadata />
</behavior>
</serviceBehaviors>
9.1 WSDL,此方式通过在服务的URL后加“?wsdl”的方式公布WSDL,可直接通过HTTP访问。
设置httpGetEnabled="true" 发布元数据(图片见上面步骤6),设置为false不发布元数据。以下为设置为false的情况:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="metadataBehavior">
<!--<serviceMetadata httpGetEnabled="true" />--> <!--设置为true公布元数据,服务可以开启,客户端也可以访问服务-->
<serviceMetadata httpGetEnabled="false" /> <!--设置为false不公布元数据,服务可以开启,但是客户端无法访问服务-->
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<!--注意此处name必须与第三步服务的命名空间一致-->
<service behaviorConfiguration="metadataBehavior" name="DBService.DBService">
<endpoint address="" binding="wsHttpBinding" contract="IContract.IContract" />
<host>
<baseAddresses>
<add baseAddress="http://127.0.0.1:8883/DBServer"/>
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
</configuration>
设置为false的情况:
9.2 MEX:此方式以一般的终结点方式公布,支持各种协议:http、tcp、NamedPipe
注意:以终结点的方式公开的元数据,无法通过浏览器查看元数据内容
添加mex终结点发布元数据,此时httpGetEnabled设置为true和false均可访问服务,只是元数据发布方式不同。
有mex终结点,httpGetEnabled="true",此时服务可以开启,客户端也可以访问服务,元数据以wsdl方式发布。
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="metadataBehavior">
<serviceMetadata httpGetEnabled="true" /> <!--设置true,则以wsdl方式发布-->
<!--<serviceMetadata httpGetEnabled="false" />--> <!--设置false,则以mex方式发布-->
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<!--注意此处name必须与第三步服务的命名空间一致-->
<service behaviorConfiguration="metadataBehavior" name="DBService.DBService">
<endpoint address="" binding="wsHttpBinding" contract="IContract.IContract" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
<host>
<baseAddresses>
<add baseAddress="http://127.0.0.1:8883/DBServer"/>
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
</configuration>
有mex终结点,httpGetEnabled="false",此时服务可以开启,客户端也可以访问服务,元数据以mex方式发布。
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="metadataBehavior">
<!--<serviceMetadata httpGetEnabled="true" />--> <!--设置true,则以wsdl方式发布-->
<serviceMetadata httpGetEnabled="false" /> <!--设置false,则以mex方式发布-->
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<!--注意此处name必须与第三步服务的命名空间一致-->
<service behaviorConfiguration="metadataBehavior" name="DBService.DBService">
<endpoint address="" binding="wsHttpBinding" contract="IContract.IContract" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
<host>
<baseAddresses>
<add baseAddress="http://127.0.0.1:8883/DBServer"/>
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
</configuration>
参考:
我的WCF之旅(2):Endpoint Overview
WCF公开服务元数据方式
整理一下思路,探讨WCF(二)
WCF元数据发布的2种方式:httpGetEnabled与mex
WCF 第五章 导出并发布元数据(服务行为)
如何:使用代码发布服务的元数据
《我的WCF之旅》博文系列汇总
WCF学习之三, 寄宿方式 代码,配置文件的更多相关文章
- WCF :IIS寄宿方式的Web地址、BaseAddress和EndPoint Address的关系
对于在IIS中通过W3SVC或WAS寄宿的WCF Service,其在浏览器中显示的地址(Web地址),与其配置文件中的BaseAddress和EndPoint Address有什么关系呢?让我们来分 ...
- WCF学习笔记1--发布使用配置文件的服务
关于WCF的入门网上资料很多,可以参考蒋金楠老师的博客http://www.cnblogs.com/artech/archive/2007/02/26/656901.html,我是从这篇博客开始学习的 ...
- (转)WCF开发框架形成之旅---WCF的几种寄宿方式
WCF寄宿方式是一种非常灵活的操作,可以在IIS服务.Windows服务.Winform程序.控制台程序中进行寄宿,从而实现WCF服务的运行,为调用者方便.高效提供服务调用.本文分别对这几种方式进行详 ...
- WCF寄宿方式
WCF开发框架形成之旅---WCF的几种寄宿方式 WCF寄宿方式是一种非常灵活的操作,可以在IIS服务.Windows服务.Winform程序.控制台程序中进行寄宿,从而实现WCF服务的运行,为调用者 ...
- WCF开发框架形成之旅---WCF的几种寄宿方式
WCF开发框架形成之旅---WCF的几种寄宿方式 WCF寄宿方式是一种非常灵活的操作,可以在IIS服务.Windows服务.Winform程序.控制台程序中进行寄宿,从而实现WCF服务的运行,为调用者 ...
- 微软 WCF的几种寄宿方式,寄宿IIS、寄宿winform、寄宿控制台、寄宿Windows服务
WCF寄宿方式是一种非常灵活的操作,可以在IIS服务.Windows服务.Winform程序.控制台程序中进行寄宿,从而实现WCF服务的运行,为调用者方便.高效提供服务调用.本文分别对这几种方式进行详 ...
- [转]WCF的几种寄宿方式
转自:WCF开发框架形成之旅---WCF的几种寄宿方式 WCF寄宿方式是一种非常灵活的操作,可以在IIS服务.Windows服务.Winform程序.控制台程序中进行寄宿,从而实现WCF服务的运行,为 ...
- 创建WCF服务自我寄宿
WCF服务的寄宿方式 WCF寄宿方式是一种非常灵活的操作,可以寄宿在各种进程之中,常见的寄宿有: IIS服务.Windows服务.Winform程序.控制台程序中进行寄宿,从而实现WCF服务的运行,为 ...
- WCF服务自我寄宿
WCF服务的寄宿方式 WCF寄宿方式是一种非常灵活的操作,可以寄宿在各种进程之中,常见的寄宿有: IIS服务.Windows服务.Winform程序.控制台程序中进行寄宿,从而实现WCF服务的运行,为 ...
随机推荐
- 通过手机音频口,实现与单片机通讯,做电子签名成功n
手机端的Ukey便携产品, 可以管理证书.加密解密.电子签名 : 1.通讯稳定,生成签名成功率100% 2.证书固化,私钥安全 3.走手机音频接口,通用.跨平台 4.耗电少,自带电池可长期供电,且可充 ...
- java 基础数据结构源码详解及数据结构算法
http://www.cnblogs.com/skywang12345/category/455711.html http://www.cnblogs.com/liqiu/p/3302607.html
- WPF ClickOnce应用程序IIS部署发布攻略
WPF程序非常适合公司内网使用,唯一缺点就是客户端要安装.net框架4.0.优势也很明显,在客户端运行的是一个WinForm程序,自动下载,可以充分利用客户机的性能,而且是以当前的Windows用户权 ...
- Workflow:采用坐标变换(移动和旋转)画箭头
背景 流程设计器的连线部分需要画一个箭头代表连接的方向,下图是期望的效果: 刚开始我准备采用三角函数(sin和cos)来计算三角的坐标,实现的过程真不爽(有兴趣的朋友可以试试),就在完工的时候,突然想 ...
- [Linux] Ubuntu下解压rar文件的方法
一般通过默认安装的ubuntu是不能解压rar文件的,只有在安装了rar解压工具之后,才可以解压.其实在ubuntu下安装rar解压工具是非常简单的,只需要两个步骤就可以迅速搞定. ubuntu 下r ...
- c++ 哈希表(hash表)
一.定义 Hash表,也称散列表.一般应用于有大量"动态"的插入(删除)和查找操作的一类问题.(如果是"静态"的,通常可以先对数据排序,查找时就可以用" ...
- iOS:风火轮活动刷新视图控件UIActivityIndicatorView的详细使用
动态风火轮视图控件:UIActivityIndicatorView 介绍:它是一种类似于风火轮旋转的视图控件,可用作刷新数据时显示加载过程所用,继承自UIView. 类型: typedef N ...
- onehot的好处,还是可以看看的
https://www.jqr.com/article/000243 一句话概括:one hot编码是将类别变量转换为机器学习算法易于利用的一种形式的过程. 类别值是分配给数据集中条目的数值编号. s ...
- 利用js动态创建<style>
var nod = document.createElement(“style”), str = “body{background:#000;color:#fff} a{color:#fff;text ...
- Spring定时器XML配置
spring-task.xml <?xml version="1.0" encoding="UTF-8"?> <beans xmlns=&qu ...