总结WCF开发中遇到的几个问题
最近的项目,需要用到WCF,在以前的工作中,经常是将WCF托管在IIS中,主要有几下几个原因:
第一:部署非常方便,和部署一个站点没什么区别;
第二:不受防火墙的影响,因为一般服务器上80端口都是开放的;
第三:IIS托管不需要程序编写托管代码。
以前WCF的绑定基本上都是用wsHttpBinding,但这次项目需要将WCF配置成MSMQ,于是我们就需要用到netMsmqBinding,在采用netMsmqBinding过程中遇到如下问题:
第一:netMsmqBinding绑定权限问题。
原来服务托管在控制台时,服务正常,但托管在windows服务时就会出现如下异常:
System.TypeInitializationException: “System.ServiceModel.Channels.Msmq”的类型初始值设定项引发异常。 ---> System.ServiceModel.MsmqException: 版本检查失败,错误为:“消息队列服务不可用 (-1072824309, 0xc00e000b)”。无法检测到 MSMQ 的版本。该队列通道上的所有操作都将失败。确保已安装 MSMQ 且 MSMQ 可用。
这条信息显示没有权限,但控制台是没问题的,原因如下:
创建消息队列是用登录帐户,而运行控制台程序也是登录帐户,所以没有权限问题,但windows服务在运行时的帐户不一定就是登录帐户,一般我们指定的是ServiceAccount.LocalSystem,于是将消息队列增加everyone权限,问题解决。
另外我将服务托管在IIS7上,总会不成功,不知道大家有没有成功过,如果有成功的,希望给个示例。队列权限为everyone,还加了个匿名用户。
第二:服务端与客户端配置不同导致不能通信,当采用默认生成的配置通信正常,采用程序编码形式编写配置,通信异常,最后发现是binding中的属性exactlyOnce值不同。这种配置主要是指服务端的配置,比如客户端的超时时间等设置就可以任意指定。
result.ExactlyOnce =false;
第三:服务托管方式问题。
由于本人还未将netMsmqBinding托管在IIS上,所以只能托管在windows服务中,本来托管在控制台也可以,但应用程序的开启比较容易受其它登录用户的影响。这托管成windows服务时遇到如下问题:
场景:我需要将同一服务程序,部署为N个不同端口不同服务名称的服务。
问题:当安装一个服务后,正常启动,在安装第二个服务时,第二个服务的执行地址会记成第一个服务的地址。
分析:有可能是windows服务在安装过程中有安装记录,即使指定了服务程序路径也会受影响,大家有啥好办法就请教。
解决方案:将服务的exe,config更改名称,例如ComputeAsyncTask_Hight_1.exe,ComputeAsyncTask_Hight_2.exe,ComputeAsyncTask_Hight_3.exe,这种情况下,安装后的执行路径就没有问题。
遗留问题:虽然上面方案能解决执行路径问题,但在如下情况下依然有问题:
当所有服务都正常安装后,再次执行安装,比如再次安装ComputeAsyncTask_Hight_1.exe,首先是服务删除,此时系统所识别的assemblypath依然是ComputeAsyncTask_Hight_3.exe,此时就会将ComputeAsyncTask_Hight_3删除,这种情况目前还未找到好的方法。
第四:如何快速彻底删除一个windows服务
当一个服务安装后,但由于某些BUG做了调整,在某种情况下就会出现无法删除服务的情况,这种问题经常消耗我大量时间去排查,我们可以借用用sc.exe这个Windows命令来解决,效果非常好,再也不用花精力去分析服务为什么不能删除的原因了。
开始——运行——cmd.exe,使用办法很简单:
sc delete "服务名" (如果服务名中间有空格,就需要前后加引号)
第五:在服务的安装类中不能引用app.config
如果将服务托管为windows服务,一般都会编写服务安装代码,这样我们就可以利用ManagedInstallerClass.InstallHelper来实现服务的自动安装,它主要是用来代替Installutil.exe手工操作。我在项目中需要将同一服务程序部署为不同端口不同服务名称的服务,所以我考虑将服务名称从app.config中指定,于是就是类似下面的代码:
service.ServiceName = ConfigurationManager.AppSettings["ServiceName"].Trim();
但在安装过程中总是报错,查明原因,是无法找到配置节,最后才知道当服务在安装时,并不是一个应用程序,理所当然就不会加载app.config,所以在安装类中我们不能调用app.config。
解决方案:将配置节从app.config中转移,比如新建一个xml文件,然后在安装时,服务名称等信息从xml配置文件中读取。
privatestring GetComputeLevel()
{
try
{
string strPath;
XmlDocument xmldoc =new XmlDocument();
XmlNode xmlnd;
strPath = System.Environment.CurrentDirectory +@"\ComputeLevelConfig.xml";
strPath = AppDomain.CurrentDomain.BaseDirectory +@"\ComputeLevelConfig.xml";
if (!File.Exists(strPath))
{
thrownew FileNotFoundException("未能找到配置文件"+strPath);
}
xmldoc.Load(strPath);
xmlnd = xmldoc.SelectSingleNode("ComputeLevelConfig");
if (null!= xmlnd)
{
return xmlnd.InnerText.Trim ();
}
else
{
thrownew Exception("没有指定计算优先级!"+ strPath);
}
}
catch (Exception ex)
{
throw ex;
}
}
以前在开发WCF时,大多都是基于默认配置,当一个服务写好之后,以后在开发新的服务,基本都是参考以前成功的案例,所以对服务端的配置文件未做过多了解。借这次机会,重 新整理下服务端配置文件的构造情况。
主体结构分为以下三个部分:
1:behaviors
默认情况会出现如下两个节点,如果想让服务端向客户端抛出详细错误,可以修改includeExceptionDetailInFaults,其它的节点我目前还未使用过。
指定绑定模式,我这里指定netMsmqBinding,下面的内容,可以补充一些与默认值不相同的内容,比如exactlyOnce,security,其它不需要额外指定的,就为默认值。
最重要的数endpoint以及host,endpoint理解ABC就行:
A:address,服务地址,如果是wshttpbing这种IIS托管形式,此处应该为空字符串,如果是非http绑定,例如netMsmqBinding,需要指定队列地址;
B:binding,绑定类型
C:contract,服务契约
host这个结点一般是针对非http绑定,用它来提供基地址,http绑定就不需要配置了。
补充1:
バインドの ExactlyOnce プロパティが true に設定されているのに、宛先キューが非トランザクション キューであるため、バインドの検証が失敗しました。サービス ホストを開けません。ExactlyOnce プロパティを false に設定するか、このバインド用のトランザクション キューを作成して、この競合を解決してください。
原因是:没有配置serviceBehaviors节点,只配置了services的
<serviceBehaviors>
<behavior name="MsmqServiceBehavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
<serviceThrottling maxConcurrentCalls="1"/>
</behavior>
</serviceBehaviors>
<services>
<service name="MsmqService" behaviorConfiguration="MsmqServiceBehavior">
<endpoint address="net.msmq://localhost/private/spc/MsmqService.svc" binding="netMsmqBinding" bindingConfiguration="MsmqBindingNonTransactionalNoSecurity" contract="IMsmqContract"/>
</service>
</services>
总结WCF开发中遇到的几个问题的更多相关文章
- WCF开发教程资源收集
WCF开发教程资源收集 1.蒋金楠,网名Artech的博客 [原创]我的WCF之旅(1):创建一个简单的WCF程序[原创]我的WCF之旅(2):Endpoint Overview[原创]我的WCF之旅 ...
- WCF开发时如何选择正确的实例模式(InstanceMode)?
WCF开发时如何选择正确的实例模式(InstanceMode)? 在使用WCF实例模型时,你是否思考过这几个的问题: ”WCF中的实例模式如何正确应用”? ”使用WCF中的实例模式有何原则可以遵循 ...
- 怎样实现IOS开发中的数据存储方式
iOS 开发中,一般有如下几种数据存储方式.需要根据具体的业务场景,选择 合适的数据存储方式. (1) 用户默认设置 – 这种情况通常不需要用户干预,如游戏通关信息,Video 播放记录,或者 Ap ...
- WCF开发实战系列一:创建第一个WCF服务
WCF开发实战系列一:创建第一个WCF服务 (原创:灰灰虫的家http://hi.baidu.com/grayworm) 在这个实战中我们将使用DataContract,ServiceContract ...
- WCF开发实战系列二:使用IIS发布WCF服务
WCF开发实战系列二:使用IIS发布WCF服务 (原创:灰灰虫的家http://hi.baidu.com/grayworm) 上一篇中,我们创建了一个简单的WCF服务,在测试的时候,我们使用VS200 ...
- WCF开发实战系列三:自运行WCF服务
WCF开发实战系列三:自运行WCF服务 (原创:灰灰虫的家 http://hi.baidu.com/grayworm)上一篇文章中我们建立了一个WCF服务站点,为WCF服务库运行提供WEB支持,我们把 ...
- WCF开发实战系列四:使用Windows服务发布WCF服务
WCF开发实战系列四:使用Windows服务发布WCF服务 (原创:灰灰虫的家http://hi.baidu.com/grayworm) 上一篇文章中我们通过编写的控制台程序或WinForm程序来为本 ...
- WCF开发实战系列五:创建WCF客户端程序
WCF开发实战系列五:创建WCF客户端程序 (原创:灰灰虫的家http://hi.baidu.com/grayworm) 在前面的三篇文章中我们分别介绍了WCF服务的三种载体:IIS.Self-Hos ...
- WCF开发实战系列一:创建第一个WCF服务 转
转 http://www.cnblogs.com/poissonnotes/archive/2010/08/28/1811064.html 在这个实战中我们将使用DataContract,Servic ...
随机推荐
- 第三个Sprint ------第一天
Github账户: 账户名称:kangqu Github地址: https://github.com/kangqu/country.git Github网站全英文,表示鸭梨山大...
- 12th final 发布评价 I
1. 约跑App——nice!:这次使用了摄像进行讲解,相比于上次能够更准确地向大家讲解,整体效果更好了,而且很好地针对同学提出的bug进行修改,能够在并不是很熟悉的领域做到这个程度已经很不容易了, ...
- vmwear导出OVF模板解析(解决ovf导入服务器失败问题,虚拟机版本等)
我们将vmwear虚拟机导出ovf模板后,有三个文件: 1,.mf 保存着.ovf和.vmdk两个文件的SHA1值,用于校验文件的完整性 2,.ovf 以XML格式保存着虚拟机的配置信息 3,.vmd ...
- VMware虚拟机安装ghost win7系统方法
原本地址:http://www.xitongcheng.com/jiaocheng/xtazjc_article_15314.html
- 原生 js 封装get ,post, delete 请求
现在的项目中都在用VUE 以及react 等MVC, MVVM 框架. 丢弃了原始的JQ .不可能为了个$.ajax();而把JQ引进来吧. 在vue1的开发中 提供了 vueResouce, vu ...
- TCP/IP之蓟辽督师 转
原创: 刘欣 码农翻身 2016-11-07 本文续<TCP/IP之大明内阁>, 不了解背景的同学可以先看看上一篇文章, 当然这篇也是<TCP/IP之大明邮差>的前传, 主要讲 ...
- PHP 使用GD 库绘制图像,无法显示的问题
根据官方GD 库绘制图像文档样式 原基本样式 $width = 120; $height = 50; $img = @imagecreatetruecolor($width, $height) or ...
- [转帖]技术盛宴 | 关于PoE以太网供电技术详解
技术盛宴 | 关于PoE以太网供电技术详解 https://smb.pconline.com.cn/1208/12085824.html [PConline 干货铺]随着物联网技术飞速发展,需要提 ...
- python 十进制整数转换为任意进制(36以内)
def baseN(num, b): return ((num == 0) and "0") or (baseN(num // b, b).lstrip("0" ...
- 免费SSL证书申请 2018年至简教程
Let’s Encrypt是国外一个公共的免费SSL项目,由 Linux 基金会托管,它的来头不小,由Mozilla.思科.Akamai.IdenTrust和EFF等组织发起,目的就是向网站自动签发和 ...