五月份的时候,有位老友给老周提了个建议:希望老周写一写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. SQL Server中的高可用性(2)----文件与文件组

        在谈到SQL Server的高可用性之前,我们首先要谈一谈单实例的高可用性.在单实例的高可用性中,不可忽略的就是文件和文件组的高可用性.SQL Server允许在某些文件损坏或离线的情况下,允 ...

  2. 【原】AFNetworking源码阅读(一)

    [原]AFNetworking源码阅读(一) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 AFNetworking版本:3.0.4 由于我平常并没有经常使用AFNetw ...

  3. 缓存、队列(Memcached、redis、RabbitMQ)

    本章内容: Memcached 简介.安装.使用 Python 操作 Memcached 天生支持集群 redis 简介.安装.使用.实例 Python 操作 Redis String.Hash.Li ...

  4. 在centos7上安装Jenkins

    在centos7上安装Jenkins 安装 添加yum repos,然后安装 sudo wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins ...

  5. C# 程序中嵌入百度地图

    本例是对WinForm中使用百度地图的简要介绍.百度地图目前支持Android开发,IOS开发,Web开发,服务接口,具体可以参照'百度地图开放平台'. [动态加载百度地图]涉及到的知识点: WebB ...

  6. EF上下文对象线程内唯一性与优化

    在一次请求中,即一个线程内,若是用到EF数据上下文对象,就创建一个,这也加是很多人的代码中习惯在使用上下文对象时,习惯将对象建立在using中,也是为了尽早释放上下文对象, 但是如果有一个业务逻辑调用 ...

  7. 浅谈JSP注释

    HTML注释 JSP文件是由HTML尿急和嵌入的Java程序片段组成的,所以在HTML中的注释同样可以在JSP文件中使用.注释格式:<!--注释内容--> <!-- 欢迎提示信息! ...

  8. 新手学习web遇到的一些乱码问题

    在新手学习web网站学习的时候经常会遇到?????这种乱码,对于刚起步的菜鸟来说真的很头痛,很容易打击继续学的信心当然了对于菜鸟的我最近也遇到过乱码问题,沉浸其中不能自拔,爱的深啊!!!!!我所遇到的 ...

  9. Openfire集群源码分析

    如果用户量增加后为了解决吞吐量问题,需要引入集群,在openfire中提供了集群的支持,另外也实现了两个集群插件:hazelcast和clustering.为了了解情况集群的工作原理,我就沿着open ...

  10. 从is(":checked")说起

    *此文所用jQuery版本应大于1.6.1   如何判断一个单选(复选)框是否选中. 对于刚接触jQuery的人,第一反应必然是. <input id="checkbox1" ...