五月份的时候,有位老友给老周提了个建议:希望老周写一写WCF的文章。其实老周以前是写过WCF的文章的,只是不是写在这个博客里,老周并不打算把X年前的博客导进来,要写的话,重新写吧。毕竟,那个时候写的文章是比较肤浅。

根据老周有限的记忆,WPF、WCF、WF、WIF等已经问世有十个年头了,老周耍.net已经十几个年头了吧,因为.net好玩、耐玩,所以一玩十来年,一直享受着优游之乐,如同当年庄子在濠梁之上所说的一样。

顺便跟各位在校的同胞们说一下,.net已不是什么新技术了,如果你认为它是新技术,表明你与你的学校实在太落后了,落后得无法用文字来形容。像WPF、WCF、WF、MEF等东东,包括现在的UWP、.net core等新玩意儿,你只能依靠自学,不走自学之路,你很难有所收获的。你一定要相信,你有自学成才的能力,想想,像老周这种笨蛋都可以完全依靠自学,你一定能的。而且,还要告诉你,老周自学的不仅仅是编程,老周自学的领域覆盖文、理,贯通天地人神鬼,涉猎古今……老周向来是爱好广,兴趣广。

那么,为啥强调自学呢?因为当今中国的大学,计算机教学水平,普通低下,低到惨不忍睹的程度。许多大学计算机老师,一辈子只见过两样东西——C/C++ 和 Java,除此二者之外,他们都不懂,教材照样年年用着上世纪90年代的书,学习工具停留在VS 6.0,所学内容严重脱离实际应用。老周一直想不明白,那些什么教授啊老师啊,研究了几十年,就研究出这点水平,也不知道他们平时都干什么去了,可能去研究妹子去,看妹子的眼光比看技术的眼光还准。

哪怕是C/C++,如果你问老师:函数传参中,int* x 和 const int& x 有什么不同,或者问 int const* x 是啥、exten "C"是什么东东,估计一些老师的反应是:这个,这个嘛,这个……现在别问这些,打基础要紧。

所以,你看看,不依靠自学,你能学到东西吗?

好了,转回咱们今天的主题。今天咱们聊聊WCF的一个基础知识——基址和默认终结点。

基址,从base address翻译过来,可能英文名字更好理解,就是给服务指定一个基础URI,而随后向服务添加的终结点的地址可以基于这个地址,当然了,添加的终结点也可以指定绝对URI。

例如,基址为http://mm.net/images/,某个终结点的相对地址为face,于是,与基址一组合,终结点的完整地址就是 http://mm.net/images/face。

再比如,基址net.tcp://192.168.1.20:999/,某个终结点的相对URI为 pay,那么,与基址组合后,终结点的完整地址为:net.tcp://192.168.1.20:999/pay。

在非IIS上运行时,比如在一个exe中承载服务,会用到ServiceHost类,实例化该host时,需要指定一个Type,它表示服务类的类型信息,至于基址,是可选的。

如果不指定基址,那么,添加的终结点就必须指定绝对URI;如果有了基址,那么添加的终结点既可以用相对URI,也可以用绝对URI。

在定义基址时,有一点要注意,相同的协议不能添加多次,比如:

http://someone:1010/sv

已经添加到基址列表中,你就不能再添加http://someone:1012/orders了,因为http协议的地址已经添加过了。不过,运行在IIS中的WCF服务可以通过以下配置来解决:

  <serviceHostingEnvironment multipleSiteBindingsEnabled="true"/>

在windows进程中host的服务就不可以了,所以,你要记住了,像下面这样指定基址是会报错的。

    <services>
<service name="sv">
<host>
<baseAddresses>
<add baseAddress="http://localhost:900/service"/>
<add baseAddress="http://localhost:1000/services/mytest"/>
<add baseAddress="http://localhost:1100/wcfservices/mytestfun"/>
</baseAddresses>
</host>
</service>
</services>

如果不是同一协议,是可以指定多个基址的,比如:

        <host>
<baseAddresses>
<add baseAddress="http://localhost:900/"/>
<add baseAddress="net.tcp://localhost:3500/services"/>
</baseAddresses>
</host>

一个是http的,一个是netTcp的,所以这两个基址是允许的。

基址介绍完了,再看看默认终结点,要使用默认终结点,一定要添加基址。所谓默认终结点,就是你不用手动去添加终结点,只要向ServiceHost指定了基址和服务类的类型,那么,运行时会根据服务类所实现的协定,自动添加终结点,终结点的地址就是基址。

比如,假设服务类实现了一个服务协定接口,并且指定了以下两个基址:

            <add baseAddress="http://localhost:6000/"/>
<add baseAddress="net.tcp://localhost:6100"/>

服务会添加两个默认终结点,针对http协议的终结点将使用basicHttpBinding,针对netTcp协议的终结点会使用NetTcpBinding,并且两个终结点的Contract都是同一个协定——服务实现的那个协定。

可以加入以下代码来检测一下:

            ServiceHost host = new ServiceHost(typeof(MyService));

            host.Open();

            foreach(ServiceEndpoint ep in host.Description.Endpoints)
{
Console.WriteLine($"地址:{ep.Address.Uri.AbsoluteUri},binding类型:{ep.Binding.GetType().Name}");
} Console.WriteLine("按任意键退出。");
Console.Read();
host.Close();

然后,你会看到以下输出。

上面的情况是我只实现了一个服务协定,那么,如果服务类实现了多个服务协定接口呢?

来,试试看。

    [ServiceContract()]
public interface IService
{
[OperationContract]
void GoodBoy(string name);
} [ServiceContract]
public interface IService2
{
[OperationContract]
void GoodGirl(string name);
}

睁大眼睛看好了,这是两个服务协定接口,然后,我们用一个服务类同时实现这两个接口。

    class MyService : IService, IService2
{
public void GoodBoy(string name)
{
// .................................
} public void GoodGirl(string name)
{
// .................................
}
}

好了,现在你知道,服务类MyService实现了两个服务协定,那么,运行时添加的默认终结点会有几个呢?不急,真相就在下面。

把上面的输出代码改一下,让其输出协定的类型名称。

            foreach (ServiceEndpoint ep in host.Description.Endpoints)
{
Console.WriteLine($"地址:{ep.Address.Uri.AbsoluteUri},binding类型:{ep.Binding.GetType().Name},协定名:{ep.Contract.ContractType.Name}");
}

运行后,看到如下内容。

为啥会变成4个终结点了?

首先,我们知道,有两个基址,分别是http和nettcp协议。

再者,服务实现了两个协定。

一个终结点由地址、绑定、协定三个主要要素组成,非主要要素可能会有Behavior、地址头等。也就是说,一个终结点只能指定一个服务协定,一个终结点只能指定一个绑定,一个终结点也只能有一个地址。

现在你明白了吧,两个协定,两个地址,所以终结点的个数 = 2 × 2,就是4个了。

依此类推,两个基址(不同协议)固定,如果服务类实现了3个协定接口,那么,运行时添加的默认终结点就有6个。

好了,今天的话题就讨论到此了,不难吧。

【WCF】基址与默认终结点的更多相关文章

  1. 在 ServiceModel 客户端配置部分中,找不到引用协定“XX”的默认终结点元素的解决方法

    今天在CRM2011中写Plugin的的时调用WCF报错,错误如下:"在 ServiceModel 客户端配置部分中,找不到引用协定"XX"的默认终结点元素.这可能是因为 ...

  2. 在 ServiceModel 客户端配置部分中,找不到引用协定“WebServiceTest.WebServiceSoap”的默认终结点元素。这可能是因为未找到应用程序的配置文件,或者是因为客户端元素

    原文  http://blog.csdn.net/bugdemo/article/details/9083497 主题 技术 在引用WebService后,程序运行到实例化WebService时报错, ...

  3. 在 ServiceModel 客户端配置部分中,找不到引用协定“PmWs.PmWebServiceSoap”的默认终结点元素

    System.Exception: ConfigManager.LoadConfigurationFromDb ServiceFactory.GetPmWebService 在 ServiceMode ...

  4. 在 ServiceModel 客户端配置部分中,找不到引用协定“IpsBarcode.ScanService”的默认终结点元素。这可能是因为未找到应用程序的配置文件,或者是因为客户端元素中找不到与此协定匹配的终结点元素。

    一个类库引用了web service A,用另一个EXE做承载时,访问这个web service A时就提示:“在 ServiceModel 客户端配置部分中,找不到引用协定“IpsBarcode.S ...

  5. 类库文件引用web服务报错解决方法-在 ServiceModel 客户端配置部分中,找不到引用协定的默认终结点元素

    由于需求,需要改造原有应用,因原有应用是写在console下面的,现在需要开放至web下, 想到BIZ层应用代码都是一样的,又不想在web下在添加引用,而重复写代码,故将原有的console下的服务和 ...

  6. 在 ServiceModel 客户端配置部分中,找不到引用协定“WebServiceSoap”的默认终结点元素。这可能是因为未找到应用程序的配置文件,或者是因为客户端元素找不到与此协定匹配的终结点元素(转)

    按语: 在项目中实现自动升级过程,在类库中调用webservice取升级update.xml文件,添加服务调用,但在类库中调用时就出现异常,但在简单的测试工程中没有问题.解决方法采用下面介绍的方法 在 ...

  7. 客服端调用自定义宿主的WCF报错"没有终结点在侦听可以接受消息的http://localhost:8085/mex。这通常是由于不正确的地址或者 SOAP 操作导致的错误"的解决方案。

    没有终结点在侦听可以接受消息的http://localhost:8085/mex.这通常是由于不正确的地址或者 SOAP 操作导致的错误. 这个错误是由于没有启动元数据交换终结点(MEX)导致的.在宿 ...

  8. WCF之多个终结点

    1.服务端配置如下(一个Service节点下可有多个endpoint,): <system.serviceModel> <services> <service name= ...

  9. 在ServiceModel客户端配置部分中,找不到引用协定“”的默认终结点元素

    鄙人自己写了一个读取文件的ASP.NET服务,在Silverlight工程中添加服务引用(名字为FileIOService)后,出现了如上的错误. 出错原因:服务是在项目B中调用的,但是主项目是A,所 ...

随机推荐

  1. 学习AOP之深入一点Spring Aop

    上一篇<学习AOP之认识一下SpringAOP>中大体的了解了代理.动态代理及SpringAop的知识.因为写的篇幅长了点所以还是再写一篇吧.接下来开始深入一点Spring aop的一些实 ...

  2. 三分钟学会用 js + css3 打造酷炫3D相册

    之前发过该文,后来不知怎么回事不见了,现在重新发一下. 中秋主题的3D旋转相册 如图,这是通过Javascript和css3来实现的.整个案例只有不到80行代码,我希望通过这个案例,让正处于迷茫期的j ...

  3. 8.仿阿里云虚拟云服务器的FTP(包括FTP文件夹大小限制)

    平台之大势何人能挡? 带着你的Net飞奔吧!:http://www.cnblogs.com/dunitian/p/4822808.html#iis 原文:http://dnt.dkill.net/Ar ...

  4. python与c互相调用

    虽然python开发效率很高,但作为脚本语言,其性能不高,所以为了兼顾开发效率和性能,通常把性能要求高的模块用c或c++来实现或者在c或c++中运行python脚本来处理逻辑,前者通常是python中 ...

  5. JQuery easyUI DataGrid 创建复杂列表头(译)

    » Create column groups in DataGrid The easyui DataGrid has ability to group columns, as the followin ...

  6. H5项目开发分享——用Canvas合成文字

    以前曾用Canvas合成.裁剪.图片等<用H5中的Canvas等技术制作海报>.这次用Canvas来画文字. 下图中"老王考到驾照后"这几个字是画在Canvas上的,与 ...

  7. 十分钟玩转 jQuery、实例大全

    一.简介 定义 jQuery创始人是美国John Resig,是优秀的Javascript框架: jQuery是一个轻量级.快速简洁的javaScript库.源码戳这 jQuery对象 jQuery产 ...

  8. Asp.Net Core 项目实战之权限管理系统(4) 依赖注入、仓储、服务的多项目分层实现

    0 Asp.Net Core 项目实战之权限管理系统(0) 无中生有 1 Asp.Net Core 项目实战之权限管理系统(1) 使用AdminLTE搭建前端 2 Asp.Net Core 项目实战之 ...

  9. iOS 原生地图地理编码与反地理编码

    当我们要在App实现功能:输入地名,编码为经纬度,实现导航功能. 那么,我需要用到原生地图中的地理编码功能,而在Core Location中主要包含了定位.地理编码(包括反编码)功能. 在文件中导入 ...

  10. 萌新笔记——vim命令“=”、“d”、“y”的用法(结合光标移动命令,一些场合会非常方便)

    vim有许多命令,网上搜有一堆贴子.文章列举出各种功能的命令. 对于"="."d"."y",我在无意中发现了它们所具有的相同的一些用法,先举 ...