在WCF中,每个终结点都包含两个不同的地址——逻辑地址和物理地址。逻辑地址就是终结点Address属性表示的地址。至于物理地址,对于消息发送放来讲,就是消息被真正发送的目的地址;而对于消息的接收放来讲,就是监听器真正监听的地址。
一、服务端的物理地址
在默认的情况下,终结点的逻辑地址和物理地址是同一个URI。换句话说,终结的逻辑地址是必须的,如何物理地址没有指定的,默认使用逻辑地址作为物理地址。对于消息接收方的终结点来讲,物理地址就是监听地址,通过ServiceEndpoint的ListenUri表示:
1: //---------------------------------------------------------------
<!--CRLF-->
2: // EndpointAddress & WCF Addressing (c) by 2008 Jiang Jin Nan
<!--CRLF-->
3: //---------------------------------------------------------------
<!--CRLF-->
4: public class ServiceEndpoint
<!--CRLF-->
5: {
<!--CRLF-->
6: ... ...
<!--CRLF-->
7: public Uri ListenUri { get; set; }
<!--CRLF-->
8: }
<!--CRLF-->
在对服务进行寄宿的时候,我们可以调用SeriviceHostBase或者ServiceHost的AddServiceEndpoint对应的重载来为添加的终结点指定ListenUri:
1: //---------------------------------------------------------------
<!--CRLF-->
2: // EndpointAddress & WCF Addressing (c) by 2008 Jiang Jin Nan
<!--CRLF-->
3: //---------------------------------------------------------------
<!--CRLF-->
4: public abstract class ServiceHostBase : CommunicationObject, IExtensibleObject<ServiceHostBase>, IDisposable
<!--CRLF-->
5: {
<!--CRLF-->
6: //... ...
<!--CRLF-->
7: public ServiceEndpoint AddServiceEndpoint(string implementedContract, Binding binding, string address, Uri listenUri);
<!--CRLF-->
8: public ServiceEndpoint AddServiceEndpoint(string implementedContract, Binding binding, Uri address, Uri listenUri);
<!--CRLF-->
9: }
<!--CRLF-->
10:
<!--CRLF-->
11: public class ServiceHost : ServiceHostBase
<!--CRLF-->
12: {
<!--CRLF-->
13: //... ...
<!--CRLF-->
14: public ServiceEndpoint AddServiceEndpoint(Type implementedContract, Binding binding, string address, Uri listenUri);
<!--CRLF-->
15: public ServiceEndpoint AddServiceEndpoint(Type implementedContract, Binding binding, Uri address, Uri listenUri);
<!--CRLF-->
16: }
<!--CRLF-->
17:
<!--CRLF-->
在下面的代码片断中,就为终结点指定了一个同于逻辑地址的物理地址(ListenUri):
1: //---------------------------------------------------------------
<!--CRLF-->
2: // ListenUri.cs (c) by 2008 Jiang Jin Nan
<!--CRLF-->
3: //---------------------------------------------------------------
<!--CRLF-->
4: using (ServiceHost serviceHost = new ServiceHost(typeof(CalculateService)))
<!--CRLF-->
5: {
<!--CRLF-->
6: serviceHost.AddServiceEndpoint(typeof(ICalculate),new WSHttpBinding(),
<!--CRLF-->
7: "http://127.0.0.1:9999/calculateservice",
<!--CRLF-->
8: new Uri ("http://127.0.0.1:8888/calculateservice"));
<!--CRLF-->
9: Console.Read();
<!--CRLF-->
10: }
<!--CRLF-->
11:
<!--CRLF-->
当然,ListenUri也可以通过配置进行指定,下面的配置和上面的代码是等效的:
1: <configuration>
<!--CRLF-->
2: <system.serviceModel>
<!--CRLF-->
3: <services>
<!--CRLF-->
4: <service name="Artech.WcfServices.Services.CalculateService">
<!--CRLF-->
5: <endpoint binding="wsHttpBinding"
<!--CRLF-->
6: contract="Artech.WcfServices.Contracts.ICalculate" address="http://127.0.0.1:8888/calculateservice"
<!--CRLF-->
7: listenUri="http://127.0.0.1:8888/calculateservice" />
<!--CRLF-->
8: </service>
<!--CRLF-->
9: </services>
<!--CRLF-->
10: </system.serviceModel>
<!--CRLF-->
11: </configuration>
<!--CRLF-->
12:
<!--CRLF-->
二、客户端的物理地址
上面我们介绍了基于消息接收端终结点物理地址的指定,现在我们来介绍对于消息发送端的终结点,物理地址如何指定。在上面我们说过,对于消息的发送端来讲,物理地址其实就是消息发送的真正目的地址。该地址通过一个特殊的EndpointBehavior,ClientViaBehavor来指定。ClientViaBehavor定义的Uri代表该物理地址。
1: //---------------------------------------------------------------
<!--CRLF-->
2: // EndpointAddress & WCF Addressing (c) by 2008 Jiang Jin Nan
<!--CRLF-->
3: //---------------------------------------------------------------
<!--CRLF-->
4: public class ClientViaBehavior : IEndpointBehavior
<!--CRLF-->
5: {
<!--CRLF-->
6: //... ...
<!--CRLF-->
7: public Uri Uri { get; set; }
<!--CRLF-->
8: }
<!--CRLF-->
ClientViaBehavor是WCF自定的EndpointBehavior, 我们可以通过下面的配置应用该ClientViaBehavor。通过<endpointBehaviors>下的<clientVia〉配置节,通过viaUri设置了一个不同于终结点地址(http://127.0.0.1:9999/calculateservice)的物理地址:http://127.0.0.1:8888/calculateservice。
1: <?xml version="1.0" encoding="utf-8" ?>
<!--CRLF-->
2: <configuration>
<!--CRLF-->
3: <system.serviceModel>
<!--CRLF-->
4: <behaviors>
<!--CRLF-->
5: <endpointBehaviors>
<!--CRLF-->
6: <behavior name="clientViaBehavior">
<!--CRLF-->
7: <clientVia viaUri="http://127.0.0.1:8888/calculateservice" />
<!--CRLF-->
8: </behavior>
<!--CRLF-->
9: </endpointBehaviors>
<!--CRLF-->
10: </behaviors>
<!--CRLF-->
11: <client>
<!--CRLF-->
12: <endpoint address="http://127.0.0.1:9999/calculateservice" behaviorConfiguration="clientViaBehavior"
<!--CRLF-->
13: binding="wsHttpBinding" bindingConfiguration="" contract="Artech.WcfServices.Contracts.ICalculate"
<!--CRLF-->
14: name="calculateservice">
<!--CRLF-->
15: </endpoint>
<!--CRLF-->
16: </client>
<!--CRLF-->
17: </system.serviceModel>
<!--CRLF-->
18: </configuration>
<!--CRLF-->
三、ListenUri和ListenUriMode
上面我们介绍了终结点的ListenUri属性用于指定一个用于网络监听的物理地址,我们接下来讨论与ListenUri相关的另一个概念——ListenUriMode。ListenUriMode代表的是确定真正监听地址的模式。ListenUriMode通过System.ServiceModel.Description.ListenUriMode枚举表示,而ListenUriMode定义了两个枚举值:Explicit和Unique。
1: //---------------------------------------------------------------
<!--CRLF-->
2: // EndpointAddress & WCF Addressing (c) by 2008 Jiang Jin Nan
<!--CRLF-->
3: //---------------------------------------------------------------
<!--CRLF-->
4: public enum ListenUriMode
<!--CRLF-->
5: {
<!--CRLF-->
6: Explicit,
<!--CRLF-->
7: Unique
<!--CRLF-->
8: }
<!--CRLF-->
ListenUriMode.Explicit表示显示采用终结点ListenUri属性设置的Uri作为最终的监听地址;而Unique则根据ListenUri采用不同的策略保证最终使用的监听地址是唯一的。而对于如何确保监听地址的唯一性,WCF采用如下的策略:
-
如果采用TCP作为传输协议,在不采用端口共享的情况下,会选择一个未被使用的端口作为最终监听地址的端口一确保地址的唯一性
-
如果采用TCP作为传输协议,同时采用端口共享情况下,会添加一个GUID作为后缀以确保地址的唯一性
-
对于非TCP作为传输协议,会添加一个GUID作为后缀以确保地址的唯一性
在ServiceEndpoint中,定义了一个ListenUriMode属性,用于指定终结点的ListenUriMode。
1: //---------------------------------------------------------------
<!--CRLF-->
2: // EndpointAddress & WCF Addressing (c) by 2008 Jiang Jin Nan
<!--CRLF-->
3: //---------------------------------------------------------------
<!--CRLF-->
4: public class ServiceEndpoint
<!--CRLF-->
5: {
<!--CRLF-->
6: //... ...
<!--CRLF-->
7: public Uri ListenUri { get; set; }
<!--CRLF-->
8: public ListenUriMode ListenUriMode { get; set; }
<!--CRLF-->
9: }
<!--CRLF-->
10:
<!--CRLF-->
在对服务进行寄宿的时候,我们可以通过代码的方式为添加的终结点指定ListenUriMode。下面的代码将终结点设置成ListenUriMode.Unique.
Co
分享到:
相关推荐
我的WCF之旅- 创建一个简单的WCF程序 - Artech WCF入门之选绝佳的例子 代源源于:《WCF全面解析 上》 编程工具:VS2010 语言:C# blog 《IIS站点中部署 WCF项目》
WCF之旅:一个简单的WCF程序(vs2010源码) 文章 + 源码 入门首选文章,折腾了好久才折腾出第一个wcf程序。 对准备学习wcf的人员绝对有意义
我的WCF之旅(1)配套代码,IIS寄宿 泛型 序列化
Apress Pro WCF 4 Practical Microsoft SOA Implementation, 2nd Part I: Introducing Windows Communication Foundation ■Chapter 1: WCF and SOA Basics ■Chapter 2: What’s New in WCF 4 ■Chapter 3: ...
我的WCF之旅源代码_创建一个简单的WCF程序
在学习WCF之旅的时候自己写得一些代码,不同的版本展示了逐渐深入的过程,有文字说明,很经典。
我的WCF之旅后续篇,呀,要大于20字符啊,废话一下
本课件包含课件,及对应源部分,为本人所做课件,可以对照文档一步步实现代码,本课件对WebService 进行了简单的介绍,WCF简单的应用 ,可以布置到各种寄宿平台上,
Artech的博客文章,我把它转成chm的格式给大家分享
WCF开发实战系列一:创建第一个WCF服务 WCF开发实战系列二:使用IIS发布WCF服务 WCF开发实战系列三:自运行WCF服务 WCF开发实战系列四:使用Windows服务发布WCF服务 WCF开发实战系列五:创建WCF客户端程序
我把WCF之旅制作了个电子书,为WCF做点贡献吧
AOP 和WCF 例子 详细 :http://blog.csdn.net/yangjian15/archive/2009/09/03/4514848.aspx
我的WCF之旅 , 主要以讲解例子为重点
摘自网友博客 非常不错的学习WCF的文章
WCF之旅 1. 创建一个简单的WCF程序 3.在WCF中实现双向通信(Bi-directional Communication) 5. 通过WCF Extension实现Localization ......
C#代码:获得链接到WCF服务的WPF客户端的IP地址
讲解WCF技术的,适合各种阶段的学习。从入门到进阶。
蒋金楠老师的wcf教程,个人看了,觉得写的很不错,对刚入门和深入了解wcf都适用,有需要的同学可下载学习
wcf教程 wcf之旅