五月份的时候,有位老友给老周提了个建议:希望老周写一写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. Microservice架构模式简介

    在2014年,Sam Newman,Martin Fowler在ThoughtWorks的一位同事,出版了一本新书<Building Microservices>.该书描述了如何按照Mic ...

  2. 查看w3wp进程占用的内存及.NET内存泄露,死锁分析

    一 基础知识 在分析之前,先上一张图: 从上面可以看到,这个w3wp进程占用了376M内存,启动了54个线程. 在使用windbg查看之前,看到的进程含有 *32 字样,意思是在64位机器上已32位方 ...

  3. Laravel 5.x 请求的生命周期(附源码)

    Laravel最早接触是刚开始实习的时候,那时通过网上的学习资料很快便上手,开发模块接口.后来没有什么深入和总结,但是当我刚开始学Laravel的时候,我对Laravel最大的认识就是,框架除了路由. ...

  4. Xamarin+Prism小试牛刀:定制跨平台Outlook邮箱应用

    通过本文你将学会如下内容: 1,如何使用Xamarin开发跨平台(Windows,Android,iOS)应用. 2,如何使用微软的登录界面登入Microsoft账号. 3,如何使用Outlook邮箱 ...

  5. 奇葩问题-TextView无法获取值

    问题场景 前几天写一个界面的时候,遇到一个非常奇葩的问题.app第一次安装的时候,这里针对用户第一次安装的时候,后来是不会出现这个问题了.我明明是对某个界面的一个textview赋值了,而且服务端也返 ...

  6. Velocity初探小结--Velocity在spring中的配置和使用

    最近正在做的项目前端使用了Velocity进行View层的数据渲染,之前没有接触过,草草过了一遍,就上手开始写,现在又回头细致的看了一遍,做个笔记. velocity是一种基于java的模板引擎技术, ...

  7. CSS知识总结(七)

    CSS常用样式 5.背景样式 1)背景颜色 background-color : transparent | color 常用值:①英文单词,②十六进制,③RGB或RGBA 另外,还有一种是 渐变色彩 ...

  8. iOS之解决崩溃Collection <__NSArrayM: 0xb550c30> was mutated while being enumerated.

    崩溃提示:Terminating app due to uncaught exception 'NSGenericException', reason: '*** Collection <CAL ...

  9. JDK安装与配置

    JDK安装与配置 一.下载 JDK是ORACLE提供免费下载使用的,官网地址:https://www.oracle.com/index.html 一般选择Java SE版本即可,企业版的选择Java ...

  10. 学习笔记:delphi之TStringGrid

    1.说明 最近加入了一个项目组,使用的开发工具是delphi6,想想又要开始搞这个工具有点小忧伤,但没办法谁让咱就是个打杂的尼... 的需求是显示一个类似于Word/excel的那种表格,可以合并列等 ...